mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-24 15:36:59 +01:00
Merge branch 'ccfix' of https://github.com/BlueWallet/BlueWallet into ccfix
This commit is contained in:
commit
3e7cf58e5a
34 changed files with 3364 additions and 396 deletions
21
blue_modules/aezeed/LICENSE
Normal file
21
blue_modules/aezeed/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 bitcoinjs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
2
blue_modules/aezeed/README.md
Normal file
2
blue_modules/aezeed/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# aezeed
|
||||
A package for encoding, decoding, and generating mnemonics of the aezeed specification. (WIP)
|
85
blue_modules/aezeed/package.json
Normal file
85
blue_modules/aezeed/package.json
Normal file
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
"_from": "aezeed",
|
||||
"_id": "aezeed@0.0.4",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-KAv2y2AtbqpdtsabCLE+C0G0h4BZLeMHsLCRga3VicYLxD17RflUBJ++c5qdpN6B6fkvK90r6bWg52Z/gMC7gQ==",
|
||||
"_location": "/aezeed",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "aezeed",
|
||||
"name": "aezeed",
|
||||
"escapedName": "aezeed",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/aezeed/-/aezeed-0.0.4.tgz",
|
||||
"_shasum": "8fce8778d34f5566328f61df7706351cb15873a9",
|
||||
"_spec": "aezeed",
|
||||
"_where": "/home/overtorment/Documents/BlueWallet",
|
||||
"author": {
|
||||
"name": "Jonathan Underwood"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/bitcoinjs/aezeed/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"aez": "^1.0.1",
|
||||
"crc-32": "npm:junderw-crc32c@^1.2.0",
|
||||
"randombytes": "^2.1.0",
|
||||
"scryptsy": "^2.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A package for encoding, decoding, and generating mnemonics of the aezeed specification.",
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.10",
|
||||
"@types/node": "^14.6.0",
|
||||
"@types/randombytes": "^2.0.0",
|
||||
"@types/scryptsy": "^2.0.0",
|
||||
"jest": "^26.4.2",
|
||||
"prettier": "^2.1.0",
|
||||
"ts-jest": "^26.2.0",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.0.2"
|
||||
},
|
||||
"files": [
|
||||
"src"
|
||||
],
|
||||
"homepage": "https://github.com/bitcoinjs/aezeed#readme",
|
||||
"keywords": [
|
||||
"aezeed",
|
||||
"bitcoin",
|
||||
"lightning",
|
||||
"lnd"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "src/cipherseed.js",
|
||||
"name": "aezeed",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/bitcoinjs/aezeed.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run clean && tsc -p tsconfig.json",
|
||||
"clean": "rm -rf src",
|
||||
"coverage": "npm run unit -- --coverage",
|
||||
"format": "npm run prettier -- --write",
|
||||
"format:ci": "npm run prettier -- --check",
|
||||
"gitdiff": "git diff --exit-code",
|
||||
"gitdiff:ci": "npm run build && npm run gitdiff",
|
||||
"lint": "tslint -p tsconfig.json -c tslint.json",
|
||||
"prepublishOnly": "npm run test && npm run gitdiff",
|
||||
"prettier": "prettier 'ts_src/**/*.ts' --single-quote --trailing-comma=all --ignore-path ./.prettierignore",
|
||||
"test": "npm run build && npm run format:ci && npm run lint && npm run unit",
|
||||
"unit": "jest --config=jest.json --runInBand"
|
||||
},
|
||||
"types": "src/cipherseed.d.ts",
|
||||
"version": "0.0.4"
|
||||
}
|
15
blue_modules/aezeed/src/cipherseed.d.ts
vendored
Normal file
15
blue_modules/aezeed/src/cipherseed.d.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
/// <reference types="node" />
|
||||
export declare class CipherSeed {
|
||||
entropy: Buffer;
|
||||
salt: Buffer;
|
||||
internalVersion: number;
|
||||
birthday: number;
|
||||
private static decipher;
|
||||
static fromMnemonic(mnemonic: string, password?: string): CipherSeed;
|
||||
static random(): CipherSeed;
|
||||
static changePassword(mnemonic: string, oldPassword: string | null, newPassword: string): string;
|
||||
constructor(entropy: Buffer, salt: Buffer, internalVersion?: number, birthday?: number);
|
||||
get birthDate(): Date;
|
||||
toMnemonic(password?: string, cipherSeedVersion?: number): string;
|
||||
private encipher;
|
||||
}
|
105
blue_modules/aezeed/src/cipherseed.js
Normal file
105
blue_modules/aezeed/src/cipherseed.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CipherSeed = void 0;
|
||||
const BlueCrypto = require('react-native-blue-crypto');
|
||||
const scrypt = require("scryptsy");
|
||||
const rng = require("randombytes");
|
||||
const mn = require("./mnemonic");
|
||||
const params_1 = require("./params");
|
||||
const aez = require('aez');
|
||||
const crc = require('junderw-crc32c');
|
||||
const BITCOIN_GENESIS = new Date('2009-01-03T18:15:05.000Z').getTime();
|
||||
const daysSinceGenesis = (time) => Math.floor((time.getTime() - BITCOIN_GENESIS) / params_1.ONE_DAY);
|
||||
|
||||
async function scryptWrapper(secret, salt, N, r, p, dkLen, progressCallback) {
|
||||
if (BlueCrypto.isAvailable()) {
|
||||
secret = Buffer.from(secret).toString('hex');
|
||||
salt = Buffer.from(salt).toString('hex');
|
||||
const hex = await BlueCrypto.scrypt(secret, salt, N, r, p, dkLen);
|
||||
return Buffer.from(hex, 'hex');
|
||||
} else {
|
||||
// fallback to js implementation
|
||||
return scrypt(secret, salt, N, r, p, dkLen, progressCallback);
|
||||
}
|
||||
}
|
||||
|
||||
class CipherSeed {
|
||||
constructor(entropy, salt, internalVersion = 0, birthday = daysSinceGenesis(new Date())) {
|
||||
this.entropy = entropy;
|
||||
this.salt = salt;
|
||||
this.internalVersion = internalVersion;
|
||||
this.birthday = birthday;
|
||||
if (entropy && entropy.length !== 16)
|
||||
throw new Error('incorrect entropy length');
|
||||
if (salt && salt.length !== 5)
|
||||
throw new Error('incorrect salt length');
|
||||
}
|
||||
|
||||
static async decipher(cipherBuf, password) {
|
||||
if (cipherBuf[0] >= params_1.PARAMS.length) {
|
||||
throw new Error('Invalid cipherSeedVersion');
|
||||
}
|
||||
const cipherSeedVersion = cipherBuf[0];
|
||||
const params = params_1.PARAMS[cipherSeedVersion];
|
||||
const checksum = Buffer.allocUnsafe(4);
|
||||
const checksumNum = crc.buf(cipherBuf.slice(0, 29));
|
||||
checksum.writeInt32BE(checksumNum);
|
||||
if (!checksum.equals(cipherBuf.slice(29))) {
|
||||
throw new Error('CRC checksum mismatch');
|
||||
}
|
||||
const salt = cipherBuf.slice(24, 29);
|
||||
const key = await scryptWrapper(Buffer.from(password, 'utf8'), salt, params.n, params.r, params.p, 32);
|
||||
const adBytes = Buffer.allocUnsafe(6);
|
||||
adBytes.writeUInt8(cipherSeedVersion, 0);
|
||||
salt.copy(adBytes, 1);
|
||||
const plainText = aez.decrypt(key, null, [adBytes], 4, cipherBuf.slice(1, 24));
|
||||
if (plainText === null)
|
||||
throw new Error('Invalid Password');
|
||||
return new CipherSeed(plainText.slice(3, 19), salt, plainText[0], plainText.readUInt16BE(1));
|
||||
}
|
||||
|
||||
static async fromMnemonic(mnemonic, password = params_1.DEFAULT_PASSWORD) {
|
||||
const bytes = mn.mnemonicToBytes(mnemonic);
|
||||
return await CipherSeed.decipher(bytes, password);
|
||||
}
|
||||
|
||||
static random() {
|
||||
return new CipherSeed(rng(16), rng(5));
|
||||
}
|
||||
|
||||
static async changePassword(mnemonic, oldPassword, newPassword) {
|
||||
const pwd = oldPassword === null ? params_1.DEFAULT_PASSWORD : oldPassword;
|
||||
const cs = await CipherSeed.fromMnemonic(mnemonic, pwd);
|
||||
return await cs.toMnemonic(newPassword);
|
||||
}
|
||||
|
||||
get birthDate() {
|
||||
return new Date(BITCOIN_GENESIS + this.birthday * params_1.ONE_DAY);
|
||||
}
|
||||
|
||||
async toMnemonic(password = params_1.DEFAULT_PASSWORD, cipherSeedVersion = params_1.CIPHER_SEED_VERSION) {
|
||||
return mn.mnemonicFromBytes(await this.encipher(password, cipherSeedVersion));
|
||||
}
|
||||
|
||||
async encipher(password, cipherSeedVersion) {
|
||||
const pwBuf = Buffer.from(password, 'utf8');
|
||||
const params = params_1.PARAMS[cipherSeedVersion];
|
||||
const key = await scryptWrapper(pwBuf, this.salt, params.n, params.r, params.p, 32);
|
||||
const seedBytes = Buffer.allocUnsafe(19);
|
||||
seedBytes.writeUInt8(this.internalVersion, 0);
|
||||
seedBytes.writeUInt16BE(this.birthday, 1);
|
||||
this.entropy.copy(seedBytes, 3);
|
||||
const adBytes = Buffer.allocUnsafe(6);
|
||||
adBytes.writeUInt8(cipherSeedVersion, 0);
|
||||
this.salt.copy(adBytes, 1);
|
||||
const cipherText = aez.encrypt(key, null, [adBytes], 4, seedBytes);
|
||||
const cipherSeedBytes = Buffer.allocUnsafe(33);
|
||||
cipherSeedBytes.writeUInt8(cipherSeedVersion, 0);
|
||||
cipherText.copy(cipherSeedBytes, 1);
|
||||
this.salt.copy(cipherSeedBytes, 24);
|
||||
const checksumNum = crc.buf(cipherSeedBytes.slice(0, 29));
|
||||
cipherSeedBytes.writeInt32BE(checksumNum, 29);
|
||||
return cipherSeedBytes;
|
||||
}
|
||||
}
|
||||
exports.CipherSeed = CipherSeed;
|
3
blue_modules/aezeed/src/mnemonic.d.ts
vendored
Normal file
3
blue_modules/aezeed/src/mnemonic.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/// <reference types="node" />
|
||||
export declare function mnemonicFromBytes(bytes: Buffer): string;
|
||||
export declare function mnemonicToBytes(mnemonic: string): Buffer;
|
2091
blue_modules/aezeed/src/mnemonic.js
Normal file
2091
blue_modules/aezeed/src/mnemonic.js
Normal file
File diff suppressed because it is too large
Load diff
8
blue_modules/aezeed/src/params.d.ts
vendored
Normal file
8
blue_modules/aezeed/src/params.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
export declare const PARAMS: {
|
||||
n: number;
|
||||
r: number;
|
||||
p: number;
|
||||
}[];
|
||||
export declare const DEFAULT_PASSWORD = "aezeed";
|
||||
export declare const CIPHER_SEED_VERSION = 0;
|
||||
export declare const ONE_DAY: number;
|
14
blue_modules/aezeed/src/params.js
Normal file
14
blue_modules/aezeed/src/params.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ONE_DAY = exports.CIPHER_SEED_VERSION = exports.DEFAULT_PASSWORD = exports.PARAMS = void 0;
|
||||
exports.PARAMS = [
|
||||
{
|
||||
// version 0
|
||||
n: 32768,
|
||||
r: 8,
|
||||
p: 1,
|
||||
},
|
||||
];
|
||||
exports.DEFAULT_PASSWORD = 'aezeed';
|
||||
exports.CIPHER_SEED_VERSION = 0;
|
||||
exports.ONE_DAY = 24 * 60 * 60 * 1000;
|
|
@ -4,7 +4,7 @@ var assert = require('assert')
|
|||
var Buffer = require('safe-buffer').Buffer
|
||||
var bs58check = require('bs58check')
|
||||
var createHash = require('create-hash')
|
||||
var scrypt = require('./scryptsy')
|
||||
var scrypt = require('scryptsy')
|
||||
var xor = require('buffer-xor/inplace')
|
||||
|
||||
var ecurve = require('ecurve')
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
test/
|
||||
.gitignore
|
||||
.min-wd
|
|
@ -1,70 +0,0 @@
|
|||
scryptsy
|
||||
========
|
||||
|
||||
[](http://travis-ci.org/cryptocoinjs/scryptsy)
|
||||
[](https://coveralls.io/r/cryptocoinjs/scryptsy)
|
||||
[](https://www.npmjs.org/package/scryptsy)
|
||||
|
||||
`scryptsy` is a pure Javascript implementation of the [scrypt][wiki] key derivation function that is fully compatible with Node.js and the browser (via Browserify).
|
||||
|
||||
|
||||
Why?
|
||||
----
|
||||
|
||||
`Scrypt` is an integral part of many crypto currencies. It's a part of the [BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) standard for encrypting private Bitcoin keys. It also serves as the [proof-of-work system](http://en.wikipedia.org/wiki/Proof-of-work_system) for many crypto currencies, most notably: Litecoin and Dogecoin.
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
npm install --save scryptsy
|
||||
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```js
|
||||
var scrypt = require('scryptsy')
|
||||
|
||||
var key = "pleaseletmein"
|
||||
var salt = "SodiumChloride"
|
||||
var data = scrypt(key, salt, 16384, 8, 1, 64)
|
||||
console.log(data.toString('hex'))
|
||||
// => 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
|
||||
```
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### scrypt(key, salt, N, r, p, keyLenBytes, [progressCallback])
|
||||
|
||||
- **key**: The key. Either `Buffer` or `string`.
|
||||
- **salt**: The salt. Either `Buffer` or `string`.
|
||||
- **N**: The number of iterations. `number` (integer)
|
||||
- **r**: Memory factor. `number` (integer)
|
||||
- **p**: Parallelization factor. `number` (integer)
|
||||
- **keyLenBytes**: The number of bytes to return. `number` (integer)
|
||||
- **progressCallback**: Call callback on every `1000` ops. Passes in `{current, total, percent}` as first parameter to `progressCallback()`.
|
||||
|
||||
Returns `Buffer`.
|
||||
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
- [Tarsnap Blurb on Scrypt][tarsnap]
|
||||
- [Scrypt Whitepaper](http://www.tarsnap.com/scrypt/scrypt.pdf)
|
||||
- [IETF Scrypt](https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00) (Test vector params are [incorrect](https://twitter.com/dchest/status/247734446881640448).)
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
[wiki]: http://en.wikipedia.org/wiki/Scrypt
|
||||
[tarsnap]: http://www.tarsnap.com/scrypt.html
|
|
@ -1,195 +0,0 @@
|
|||
/* eslint-disable camelcase */
|
||||
let pbkdf2 = require('pbkdf2')
|
||||
|
||||
var MAX_VALUE = 0x7fffffff
|
||||
|
||||
// N = Cpu cost, r = Memory cost, p = parallelization cost
|
||||
async function scrypt (key, salt, N, r, p, dkLen, progressCallback) {
|
||||
if (N === 0 || (N & (N - 1)) !== 0) throw Error('N must be > 0 and a power of 2')
|
||||
|
||||
if (N > MAX_VALUE / 128 / r) throw Error('Parameter N is too large')
|
||||
if (r > MAX_VALUE / 128 / p) throw Error('Parameter r is too large')
|
||||
|
||||
var XY = Buffer.alloc(256 * r)
|
||||
var V = Buffer.alloc(128 * r * N)
|
||||
|
||||
// pseudo global
|
||||
var B32 = new Int32Array(16) // salsa20_8
|
||||
var x = new Int32Array(16) // salsa20_8
|
||||
var _X = Buffer.alloc(64) // blockmix_salsa8
|
||||
|
||||
// pseudo global
|
||||
var B = pbkdf2.pbkdf2Sync(key, salt, 1, p * 128 * r, 'sha256')
|
||||
|
||||
var tickCallback
|
||||
if (progressCallback) {
|
||||
var totalOps = p * N * 2
|
||||
var currentOp = 0
|
||||
|
||||
tickCallback = function () {
|
||||
return new Promise(function(resolve, reject) {
|
||||
++currentOp
|
||||
|
||||
// send progress notifications once every 1,000 ops
|
||||
if (currentOp % 1000 === 0) {
|
||||
progressCallback({
|
||||
current: currentOp,
|
||||
total: totalOps,
|
||||
percent: (currentOp / totalOps) * 100.0
|
||||
})
|
||||
setTimeout(resolve, 10)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < p; i++) {
|
||||
await smix(B, i * 128 * r, r, N, V, XY)
|
||||
if (typeof shold_stop_bip38 !== 'undefined') break;
|
||||
}
|
||||
|
||||
return pbkdf2.pbkdf2Sync(key, B, 1, dkLen, 'sha256')
|
||||
|
||||
// all of these functions are actually moved to the top
|
||||
// due to function hoisting
|
||||
|
||||
async function smix (B, Bi, r, N, V, XY) {
|
||||
var Xi = 0
|
||||
var Yi = 128 * r
|
||||
var i
|
||||
|
||||
B.copy(XY, Xi, Bi, Bi + Yi)
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
XY.copy(V, i * Yi, Xi, Xi + Yi)
|
||||
blockmix_salsa8(XY, Xi, Yi, r)
|
||||
|
||||
if (tickCallback) {
|
||||
await tickCallback()
|
||||
if (typeof shold_stop_bip38 !== 'undefined') break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
var offset = Xi + (2 * r - 1) * 64
|
||||
var j = XY.readUInt32LE(offset) & (N - 1)
|
||||
blockxor(V, j * Yi, XY, Xi, Yi)
|
||||
blockmix_salsa8(XY, Xi, Yi, r)
|
||||
|
||||
if (tickCallback) {
|
||||
await tickCallback()
|
||||
if (typeof shold_stop_bip38 !== 'undefined') break;
|
||||
}
|
||||
}
|
||||
|
||||
XY.copy(B, Bi, Xi, Xi + Yi)
|
||||
}
|
||||
|
||||
function blockmix_salsa8 (BY, Bi, Yi, r) {
|
||||
var i
|
||||
|
||||
arraycopy(BY, Bi + (2 * r - 1) * 64, _X, 0, 64)
|
||||
|
||||
for (i = 0; i < 2 * r; i++) {
|
||||
blockxor(BY, i * 64, _X, 0, 64)
|
||||
salsa20_8(_X)
|
||||
arraycopy(_X, 0, BY, Yi + (i * 64), 64)
|
||||
}
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
arraycopy(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64)
|
||||
}
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
arraycopy(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64)
|
||||
}
|
||||
}
|
||||
|
||||
function R (a, b) {
|
||||
return (a << b) | (a >>> (32 - b))
|
||||
}
|
||||
|
||||
function salsa20_8 (B) {
|
||||
var i
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
B32[i] = (B[i * 4 + 0] & 0xff) << 0
|
||||
B32[i] |= (B[i * 4 + 1] & 0xff) << 8
|
||||
B32[i] |= (B[i * 4 + 2] & 0xff) << 16
|
||||
B32[i] |= (B[i * 4 + 3] & 0xff) << 24
|
||||
// B32[i] = B.readUInt32LE(i*4) <--- this is signficantly slower even in Node.js
|
||||
}
|
||||
|
||||
arraycopy(B32, 0, x, 0, 16)
|
||||
|
||||
for (i = 8; i > 0; i -= 2) {
|
||||
x[4] ^= R(x[0] + x[12], 7)
|
||||
x[8] ^= R(x[4] + x[0], 9)
|
||||
x[12] ^= R(x[8] + x[4], 13)
|
||||
x[0] ^= R(x[12] + x[8], 18)
|
||||
x[9] ^= R(x[5] + x[1], 7)
|
||||
x[13] ^= R(x[9] + x[5], 9)
|
||||
x[1] ^= R(x[13] + x[9], 13)
|
||||
x[5] ^= R(x[1] + x[13], 18)
|
||||
x[14] ^= R(x[10] + x[6], 7)
|
||||
x[2] ^= R(x[14] + x[10], 9)
|
||||
x[6] ^= R(x[2] + x[14], 13)
|
||||
x[10] ^= R(x[6] + x[2], 18)
|
||||
x[3] ^= R(x[15] + x[11], 7)
|
||||
x[7] ^= R(x[3] + x[15], 9)
|
||||
x[11] ^= R(x[7] + x[3], 13)
|
||||
x[15] ^= R(x[11] + x[7], 18)
|
||||
x[1] ^= R(x[0] + x[3], 7)
|
||||
x[2] ^= R(x[1] + x[0], 9)
|
||||
x[3] ^= R(x[2] + x[1], 13)
|
||||
x[0] ^= R(x[3] + x[2], 18)
|
||||
x[6] ^= R(x[5] + x[4], 7)
|
||||
x[7] ^= R(x[6] + x[5], 9)
|
||||
x[4] ^= R(x[7] + x[6], 13)
|
||||
x[5] ^= R(x[4] + x[7], 18)
|
||||
x[11] ^= R(x[10] + x[9], 7)
|
||||
x[8] ^= R(x[11] + x[10], 9)
|
||||
x[9] ^= R(x[8] + x[11], 13)
|
||||
x[10] ^= R(x[9] + x[8], 18)
|
||||
x[12] ^= R(x[15] + x[14], 7)
|
||||
x[13] ^= R(x[12] + x[15], 9)
|
||||
x[14] ^= R(x[13] + x[12], 13)
|
||||
x[15] ^= R(x[14] + x[13], 18)
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
var bi = i * 4
|
||||
B[bi + 0] = (B32[i] >> 0 & 0xff)
|
||||
B[bi + 1] = (B32[i] >> 8 & 0xff)
|
||||
B[bi + 2] = (B32[i] >> 16 & 0xff)
|
||||
B[bi + 3] = (B32[i] >> 24 & 0xff)
|
||||
// B.writeInt32LE(B32[i], i*4) //<--- this is signficantly slower even in Node.js
|
||||
}
|
||||
}
|
||||
|
||||
// naive approach... going back to loop unrolling may yield additional performance
|
||||
function blockxor (S, Si, D, Di, len) {
|
||||
for (var i = 0; i < len; i++) {
|
||||
D[Di + i] ^= S[Si + i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function arraycopy (src, srcPos, dest, destPos, length) {
|
||||
if (Buffer.isBuffer(src) && Buffer.isBuffer(dest)) {
|
||||
src.copy(dest, destPos, srcPos, srcPos + length)
|
||||
} else {
|
||||
while (length--) {
|
||||
dest[destPos++] = src[srcPos++]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = scrypt
|
|
@ -1,87 +0,0 @@
|
|||
{
|
||||
"_from": "scryptsy@^2.0.0",
|
||||
"_id": "scryptsy@2.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-Jiw28CMc+nZU4jY/o5TNLexm83g=",
|
||||
"_location": "/scryptsy",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "scryptsy@^2.0.0",
|
||||
"name": "scryptsy",
|
||||
"escapedName": "scryptsy",
|
||||
"rawSpec": "^2.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.0.0.tgz",
|
||||
"_shasum": "262c36f0231cfa7654e2363fa394cd2dec66f378",
|
||||
"_spec": "scryptsy@^2.0.0",
|
||||
"_where": "/home/burn/Documents/bip38",
|
||||
"author": "",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cryptocoinjs/scryptsy/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Pure JavaScript implementation of the scrypt key deriviation function that is fully compatible with Node.js and the browser.",
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.10.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"mocha": "^2.2.0",
|
||||
"mochify": "^2.1.0",
|
||||
"standard": "^7.1.1"
|
||||
},
|
||||
"homepage": "https://github.com/cryptocoinjs/scryptsy#readme",
|
||||
"keywords": [
|
||||
"crytpo",
|
||||
"cryptography",
|
||||
"scrypt",
|
||||
"kdf",
|
||||
"litecoin",
|
||||
"dogecoin",
|
||||
"bitcoin",
|
||||
"bip38"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/scrypt.js",
|
||||
"name": "scryptsy",
|
||||
"repository": {
|
||||
"url": "git+ssh://git@github.com/cryptocoinjs/scryptsy.git",
|
||||
"type": "git"
|
||||
},
|
||||
"scripts": {
|
||||
"browser-test": "mochify --wd -R spec",
|
||||
"coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter list test/*.js",
|
||||
"coveralls": "npm run-script coverage && node ./node_modules/.bin/coveralls < coverage/lcov.info",
|
||||
"lint": "standard",
|
||||
"test": "mocha --ui bdd",
|
||||
"unit": "mocha"
|
||||
},
|
||||
"version": "2.0.0",
|
||||
"react-native": {
|
||||
"path": "path-browserify",
|
||||
"fs": "react-native-level-fs",
|
||||
"_stream_transform": "readable-stream/transform",
|
||||
"_stream_readable": "readable-stream/readable",
|
||||
"_stream_writable": "readable-stream/writable",
|
||||
"_stream_duplex": "readable-stream/duplex",
|
||||
"_stream_passthrough": "readable-stream/passthrough",
|
||||
"stream": "stream-browserify"
|
||||
},
|
||||
"browser": {
|
||||
"path": "path-browserify",
|
||||
"fs": "react-native-level-fs",
|
||||
"_stream_transform": "readable-stream/transform",
|
||||
"_stream_readable": "readable-stream/readable",
|
||||
"_stream_writable": "readable-stream/writable",
|
||||
"_stream_duplex": "readable-stream/duplex",
|
||||
"_stream_passthrough": "readable-stream/passthrough",
|
||||
"stream": "stream-browserify"
|
||||
}
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
3.0.0 / 2019-03-12
|
||||
------------------
|
||||
- **breaking** Import gives an object with two functions `scrypt` and `scryptSync`
|
||||
- `scryptSync` is the old synchronus function.
|
||||
- `scrypt` will return a promise with the buffer.
|
||||
|
||||
2.0.0 / 2016-05-26
|
||||
------------------
|
||||
- **breaking** Node v0.10 not supported anymore.
|
21
blue_modules/scryptsy/LICENSE
Normal file
21
blue_modules/scryptsy/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 cryptocoinjs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
157
blue_modules/scryptsy/README.md
Normal file
157
blue_modules/scryptsy/README.md
Normal file
|
@ -0,0 +1,157 @@
|
|||
scryptsy
|
||||
========
|
||||
|
||||
[](http://travis-ci.org/cryptocoinjs/scryptsy)
|
||||
[](https://coveralls.io/r/cryptocoinjs/scryptsy)
|
||||
[](https://www.npmjs.org/package/scryptsy)
|
||||
|
||||
`scryptsy` is a pure Javascript implementation of the [scrypt][wiki] key derivation function that is fully compatible with Node.js and the browser (via Browserify).
|
||||
|
||||
|
||||
Why?
|
||||
----
|
||||
|
||||
`Scrypt` is an integral part of many crypto currencies. It's a part of the [BIP38](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) standard for encrypting private Bitcoin keys. It also serves as the [proof-of-work system](http://en.wikipedia.org/wiki/Proof-of-work_system) for many crypto currencies, most notably: Litecoin and Dogecoin.
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
npm install --save scryptsy
|
||||
|
||||
|
||||
|
||||
Browserify Note
|
||||
------------
|
||||
|
||||
When using a browserified bundle, be sure to add `setImmediate` as a shim.
|
||||
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```js
|
||||
const scrypt = require('scryptsy')
|
||||
|
||||
async function main () {
|
||||
var key = "pleaseletmein"
|
||||
var salt = "SodiumChloride"
|
||||
var data1 = scrypt(key, salt, 16384, 8, 1, 64)
|
||||
console.log(data1.toString('hex'))
|
||||
// => 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
|
||||
|
||||
// async is actually slower, but it will free up the event loop occasionally
|
||||
// which will allow for front end GUI elements to update and cause it to not
|
||||
// freeze up.
|
||||
// See benchmarks below
|
||||
// Passing 300 below means every 300 iterations internally will call setImmediate once
|
||||
var data2 = await scrypt.async(key, salt, 16384, 8, 1, 64, undefined, 300)
|
||||
console.log(data2.toString('hex'))
|
||||
// => 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
|
||||
}
|
||||
main().catch(console.error)
|
||||
```
|
||||
|
||||
|
||||
Benchmarks
|
||||
-------
|
||||
|
||||
Internal iterations are N * p, so changing r doesn't affect the number of calls to setImmediate.
|
||||
Decreasing pI decreases performance in exchange for more frequently freeing the event loop.
|
||||
(pI Default is 5000 loops per setImmediate call)
|
||||
|
||||
Note: these benchmarks were done on node v10 on a CPU with good single thread performance.
|
||||
browsers show a much larger difference. Please tinker with the pI setting to balance between
|
||||
performance and GUI responsiveness.
|
||||
|
||||
If `pI >= N`, setImmediate will only be called `p * 2` times total (on the i = 0 of each for loop).
|
||||
|
||||
```
|
||||
---------------------------
|
||||
time : type : (N,r,p,pI) (pI = promiseInterval)
|
||||
---------------------------
|
||||
2266 ms : sync (2^16,16,1)
|
||||
2548 ms : async (2^16,16,1,5000)
|
||||
12.44% increase
|
||||
---------------------------
|
||||
2616 ms : sync (2^16,1,16)
|
||||
2995 ms : async (2^16,1,16,5000)
|
||||
14.49% increase
|
||||
---------------------------
|
||||
2685 ms : sync (2^20,1,1)
|
||||
3090 ms : async (2^20,1,1,5000)
|
||||
15.08% increase
|
||||
---------------------------
|
||||
2235 ms : sync (2^16,16,1)
|
||||
2627 ms : async (2^16,16,1,10)
|
||||
17.54% increase
|
||||
---------------------------
|
||||
2592 ms : sync (2^16,1,16)
|
||||
3305 ms : async (2^16,1,16,10)
|
||||
27.51% increase
|
||||
---------------------------
|
||||
2705 ms : sync (2^20,1,1)
|
||||
3363 ms : async (2^20,1,1,10)
|
||||
24.33% increase
|
||||
---------------------------
|
||||
2278 ms : sync (2^16,16,1)
|
||||
2773 ms : async (2^16,16,1,1)
|
||||
21.73% increase
|
||||
---------------------------
|
||||
2617 ms : sync (2^16,1,16)
|
||||
5632 ms : async (2^16,1,16,1)
|
||||
115.21% increase
|
||||
---------------------------
|
||||
2727 ms : sync (2^20,1,1)
|
||||
5723 ms : async (2^20,1,1,1)
|
||||
109.86% increase
|
||||
---------------------------
|
||||
```
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### scrypt(key, salt, N, r, p, keyLenBytes, [progressCallback])
|
||||
|
||||
- **key**: The key. Either `Buffer` or `string`.
|
||||
- **salt**: The salt. Either `Buffer` or `string`.
|
||||
- **N**: The number of iterations. `number` (integer)
|
||||
- **r**: Memory factor. `number` (integer)
|
||||
- **p**: Parallelization factor. `number` (integer)
|
||||
- **keyLenBytes**: The number of bytes to return. `number` (integer)
|
||||
- **progressCallback**: Call callback on every `1000` ops. Passes in `{current, total, percent}` as first parameter to `progressCallback()`.
|
||||
|
||||
Returns `Buffer`.
|
||||
|
||||
### scrypt.async(key, salt, N, r, p, keyLenBytes, [progressCallback, promiseInterval])
|
||||
|
||||
- **key**: The key. Either `Buffer` or `string`.
|
||||
- **salt**: The salt. Either `Buffer` or `string`.
|
||||
- **N**: The number of iterations. `number` (integer)
|
||||
- **r**: Memory factor. `number` (integer)
|
||||
- **p**: Parallelization factor. `number` (integer)
|
||||
- **keyLenBytes**: The number of bytes to return. `number` (integer)
|
||||
- **progressCallback**: Call callback on every `1000` ops. Passes in `{current, total, percent}` as first parameter to `progressCallback()`.
|
||||
- **promiseInterval**: The number of internal iterations before calling setImmediate once to free the event loop.
|
||||
|
||||
Returns `Promise<Buffer>`.
|
||||
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
- [Tarsnap Blurb on Scrypt][tarsnap]
|
||||
- [Scrypt Whitepaper](http://www.tarsnap.com/scrypt/scrypt.pdf)
|
||||
- [IETF Scrypt](https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00) (Test vector params are [incorrect](https://twitter.com/dchest/status/247734446881640448).)
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
[wiki]: http://en.wikipedia.org/wiki/Scrypt
|
||||
[tarsnap]: http://www.tarsnap.com/scrypt.html
|
3
blue_modules/scryptsy/lib/index.js
Normal file
3
blue_modules/scryptsy/lib/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const scrypt = require('./scryptSync')
|
||||
scrypt.async = require('./scrypt')
|
||||
module.exports = scrypt
|
26
blue_modules/scryptsy/lib/scrypt.js
Normal file
26
blue_modules/scryptsy/lib/scrypt.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
let pbkdf2 = require('pbkdf2')
|
||||
const {
|
||||
checkAndInit,
|
||||
smix
|
||||
} = require('./utils')
|
||||
|
||||
// N = Cpu cost, r = Memory cost, p = parallelization cost
|
||||
async function scrypt (key, salt, N, r, p, dkLen, progressCallback, promiseInterval) {
|
||||
const {
|
||||
XY,
|
||||
V,
|
||||
B32,
|
||||
x,
|
||||
_X,
|
||||
B,
|
||||
tickCallback
|
||||
} = checkAndInit(key, salt, N, r, p, dkLen, progressCallback)
|
||||
|
||||
for (var i = 0; i < p; i++) {
|
||||
await smix(B, i * 128 * r, r, N, V, XY, _X, B32, x, tickCallback, promiseInterval)
|
||||
}
|
||||
|
||||
return pbkdf2.pbkdf2Sync(key, B, 1, dkLen, 'sha256')
|
||||
}
|
||||
|
||||
module.exports = scrypt
|
26
blue_modules/scryptsy/lib/scryptSync.js
Normal file
26
blue_modules/scryptsy/lib/scryptSync.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
let pbkdf2 = require('pbkdf2')
|
||||
const {
|
||||
checkAndInit,
|
||||
smixSync
|
||||
} = require('./utils')
|
||||
|
||||
// N = Cpu cost, r = Memory cost, p = parallelization cost
|
||||
function scrypt (key, salt, N, r, p, dkLen, progressCallback) {
|
||||
const {
|
||||
XY,
|
||||
V,
|
||||
B32,
|
||||
x,
|
||||
_X,
|
||||
B,
|
||||
tickCallback
|
||||
} = checkAndInit(key, salt, N, r, p, dkLen, progressCallback)
|
||||
|
||||
for (var i = 0; i < p; i++) {
|
||||
smixSync(B, i * 128 * r, r, N, V, XY, _X, B32, x, tickCallback)
|
||||
}
|
||||
|
||||
return pbkdf2.pbkdf2Sync(key, B, 1, dkLen, 'sha256')
|
||||
}
|
||||
|
||||
module.exports = scrypt
|
216
blue_modules/scryptsy/lib/utils.js
Normal file
216
blue_modules/scryptsy/lib/utils.js
Normal file
|
@ -0,0 +1,216 @@
|
|||
let pbkdf2 = require('pbkdf2')
|
||||
const MAX_VALUE = 0x7fffffff
|
||||
const DEFAULT_PROMISE_INTERVAL = 5000
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
function checkAndInit (key, salt, N, r, p, dkLen, progressCallback) {
|
||||
if (N === 0 || (N & (N - 1)) !== 0) throw Error('N must be > 0 and a power of 2')
|
||||
|
||||
if (N > MAX_VALUE / 128 / r) throw Error('Parameter N is too large')
|
||||
if (r > MAX_VALUE / 128 / p) throw Error('Parameter r is too large')
|
||||
|
||||
let XY = Buffer.alloc(256 * r)
|
||||
let V = Buffer.alloc(128 * r * N)
|
||||
|
||||
// pseudo global
|
||||
let B32 = new Int32Array(16) // salsa20_8
|
||||
let x = new Int32Array(16) // salsa20_8
|
||||
let _X = Buffer.alloc(64) // blockmix_salsa8
|
||||
|
||||
// pseudo global
|
||||
let B = pbkdf2.pbkdf2Sync(key, salt, 1, p * 128 * r, 'sha256')
|
||||
|
||||
let tickCallback
|
||||
if (progressCallback) {
|
||||
let totalOps = p * N * 2
|
||||
let currentOp = 0
|
||||
|
||||
tickCallback = function () {
|
||||
++currentOp
|
||||
|
||||
// send progress notifications once every 1,000 ops
|
||||
if (currentOp % 1000 === 0) {
|
||||
progressCallback({
|
||||
current: currentOp,
|
||||
total: totalOps,
|
||||
percent: (currentOp / totalOps) * 100.0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
XY,
|
||||
V,
|
||||
B32,
|
||||
x,
|
||||
_X,
|
||||
B,
|
||||
tickCallback
|
||||
}
|
||||
}
|
||||
|
||||
async function smix (B, Bi, r, N, V, XY, _X, B32, x, tickCallback, promiseInterval) {
|
||||
promiseInterval = promiseInterval || DEFAULT_PROMISE_INTERVAL
|
||||
let Xi = 0
|
||||
let Yi = 128 * r
|
||||
let i
|
||||
|
||||
B.copy(XY, Xi, Bi, Bi + Yi)
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
XY.copy(V, i * Yi, Xi, Xi + Yi)
|
||||
if (i % promiseInterval === 0) {
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
}
|
||||
blockmix_salsa8(XY, Xi, Yi, r, _X, B32, x)
|
||||
|
||||
if (tickCallback) tickCallback()
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
let offset = Xi + (2 * r - 1) * 64
|
||||
let j = XY.readUInt32LE(offset) & (N - 1)
|
||||
blockxor(V, j * Yi, XY, Xi, Yi)
|
||||
if (i % promiseInterval === 0) {
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
}
|
||||
blockmix_salsa8(XY, Xi, Yi, r, _X, B32, x)
|
||||
|
||||
if (tickCallback) tickCallback()
|
||||
}
|
||||
|
||||
XY.copy(B, Bi, Xi, Xi + Yi)
|
||||
}
|
||||
|
||||
function smixSync (B, Bi, r, N, V, XY, _X, B32, x, tickCallback) {
|
||||
let Xi = 0
|
||||
let Yi = 128 * r
|
||||
let i
|
||||
|
||||
B.copy(XY, Xi, Bi, Bi + Yi)
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
XY.copy(V, i * Yi, Xi, Xi + Yi)
|
||||
blockmix_salsa8(XY, Xi, Yi, r, _X, B32, x)
|
||||
|
||||
if (tickCallback) tickCallback()
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
let offset = Xi + (2 * r - 1) * 64
|
||||
let j = XY.readUInt32LE(offset) & (N - 1)
|
||||
blockxor(V, j * Yi, XY, Xi, Yi)
|
||||
blockmix_salsa8(XY, Xi, Yi, r, _X, B32, x)
|
||||
|
||||
if (tickCallback) tickCallback()
|
||||
}
|
||||
|
||||
XY.copy(B, Bi, Xi, Xi + Yi)
|
||||
}
|
||||
|
||||
function blockmix_salsa8 (BY, Bi, Yi, r, _X, B32, x) {
|
||||
let i
|
||||
|
||||
arraycopy(BY, Bi + (2 * r - 1) * 64, _X, 0, 64)
|
||||
|
||||
for (i = 0; i < 2 * r; i++) {
|
||||
blockxor(BY, i * 64, _X, 0, 64)
|
||||
salsa20_8(_X, B32, x)
|
||||
arraycopy(_X, 0, BY, Yi + (i * 64), 64)
|
||||
}
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
arraycopy(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64)
|
||||
}
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
arraycopy(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64)
|
||||
}
|
||||
}
|
||||
|
||||
function R (a, b) {
|
||||
return (a << b) | (a >>> (32 - b))
|
||||
}
|
||||
|
||||
function salsa20_8 (B, B32, x) {
|
||||
let i
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
B32[i] = (B[i * 4 + 0] & 0xff) << 0
|
||||
B32[i] |= (B[i * 4 + 1] & 0xff) << 8
|
||||
B32[i] |= (B[i * 4 + 2] & 0xff) << 16
|
||||
B32[i] |= (B[i * 4 + 3] & 0xff) << 24
|
||||
// B32[i] = B.readUInt32LE(i*4) <--- this is signficantly slower even in Node.js
|
||||
}
|
||||
|
||||
arraycopy(B32, 0, x, 0, 16)
|
||||
|
||||
for (i = 8; i > 0; i -= 2) {
|
||||
x[4] ^= R(x[0] + x[12], 7)
|
||||
x[8] ^= R(x[4] + x[0], 9)
|
||||
x[12] ^= R(x[8] + x[4], 13)
|
||||
x[0] ^= R(x[12] + x[8], 18)
|
||||
x[9] ^= R(x[5] + x[1], 7)
|
||||
x[13] ^= R(x[9] + x[5], 9)
|
||||
x[1] ^= R(x[13] + x[9], 13)
|
||||
x[5] ^= R(x[1] + x[13], 18)
|
||||
x[14] ^= R(x[10] + x[6], 7)
|
||||
x[2] ^= R(x[14] + x[10], 9)
|
||||
x[6] ^= R(x[2] + x[14], 13)
|
||||
x[10] ^= R(x[6] + x[2], 18)
|
||||
x[3] ^= R(x[15] + x[11], 7)
|
||||
x[7] ^= R(x[3] + x[15], 9)
|
||||
x[11] ^= R(x[7] + x[3], 13)
|
||||
x[15] ^= R(x[11] + x[7], 18)
|
||||
x[1] ^= R(x[0] + x[3], 7)
|
||||
x[2] ^= R(x[1] + x[0], 9)
|
||||
x[3] ^= R(x[2] + x[1], 13)
|
||||
x[0] ^= R(x[3] + x[2], 18)
|
||||
x[6] ^= R(x[5] + x[4], 7)
|
||||
x[7] ^= R(x[6] + x[5], 9)
|
||||
x[4] ^= R(x[7] + x[6], 13)
|
||||
x[5] ^= R(x[4] + x[7], 18)
|
||||
x[11] ^= R(x[10] + x[9], 7)
|
||||
x[8] ^= R(x[11] + x[10], 9)
|
||||
x[9] ^= R(x[8] + x[11], 13)
|
||||
x[10] ^= R(x[9] + x[8], 18)
|
||||
x[12] ^= R(x[15] + x[14], 7)
|
||||
x[13] ^= R(x[12] + x[15], 9)
|
||||
x[14] ^= R(x[13] + x[12], 13)
|
||||
x[15] ^= R(x[14] + x[13], 18)
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
let bi = i * 4
|
||||
B[bi + 0] = (B32[i] >> 0 & 0xff)
|
||||
B[bi + 1] = (B32[i] >> 8 & 0xff)
|
||||
B[bi + 2] = (B32[i] >> 16 & 0xff)
|
||||
B[bi + 3] = (B32[i] >> 24 & 0xff)
|
||||
// B.writeInt32LE(B32[i], i*4) //<--- this is signficantly slower even in Node.js
|
||||
}
|
||||
}
|
||||
|
||||
// naive approach... going back to loop unrolling may yield additional performance
|
||||
function blockxor (S, Si, D, Di, len) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
D[Di + i] ^= S[Si + i]
|
||||
}
|
||||
}
|
||||
|
||||
function arraycopy (src, srcPos, dest, destPos, length) {
|
||||
if (Buffer.isBuffer(src) && Buffer.isBuffer(dest)) {
|
||||
src.copy(dest, destPos, srcPos, srcPos + length)
|
||||
} else {
|
||||
while (length--) {
|
||||
dest[destPos++] = src[srcPos++]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkAndInit,
|
||||
smix,
|
||||
smixSync
|
||||
}
|
71
blue_modules/scryptsy/package.json
Normal file
71
blue_modules/scryptsy/package.json
Normal file
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"_from": "scryptsy@2.1.0",
|
||||
"_id": "scryptsy@2.1.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==",
|
||||
"_location": "/scryptsy",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "scryptsy@2.1.0",
|
||||
"name": "scryptsy",
|
||||
"escapedName": "scryptsy",
|
||||
"rawSpec": "2.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz",
|
||||
"_shasum": "8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790",
|
||||
"_spec": "scryptsy@2.1.0",
|
||||
"_where": "/home/overtorment/Documents/BlueWallet",
|
||||
"author": "",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cryptocoinjs/scryptsy/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Pure JavaScript implementation of the scrypt key deriviation function that is fully compatible with Node.js and the browser.",
|
||||
"devDependencies": {
|
||||
"coveralls": "^3.0.3",
|
||||
"mocha": "^6.0.2",
|
||||
"mochify": "^6.1.0",
|
||||
"nyc": "^13.3.0",
|
||||
"standard": "^12.0.1"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"homepage": "https://github.com/cryptocoinjs/scryptsy#readme",
|
||||
"keywords": [
|
||||
"crytpo",
|
||||
"cryptography",
|
||||
"scrypt",
|
||||
"kdf",
|
||||
"litecoin",
|
||||
"dogecoin",
|
||||
"bitcoin",
|
||||
"bip38"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"name": "scryptsy",
|
||||
"repository": {
|
||||
"url": "git+ssh://git@github.com/cryptocoinjs/scryptsy.git",
|
||||
"type": "git"
|
||||
},
|
||||
"scripts": {
|
||||
"browser-test": "mochify --wd -R spec",
|
||||
"coverage": "nyc --check-coverage --statements 80 --branches 60 --functions 90 --lines 90 mocha",
|
||||
"coveralls": "npm run-script coverage && coveralls < coverage/lcov.info",
|
||||
"lint": "standard",
|
||||
"test": "mocha --ui bdd",
|
||||
"unit": "mocha"
|
||||
},
|
||||
"version": "2.1.0"
|
||||
}
|
|
@ -14,6 +14,7 @@ import {
|
|||
LightningCustodianWallet,
|
||||
HDLegacyElectrumSeedP2PKHWallet,
|
||||
HDSegwitElectrumSeedP2WPKHWallet,
|
||||
HDAezeedWallet,
|
||||
MultisigHDWallet,
|
||||
} from './';
|
||||
const encryption = require('../blue_modules/encryption');
|
||||
|
@ -275,6 +276,9 @@ export class AppStorage {
|
|||
case MultisigHDWallet.type:
|
||||
unserializedWallet = MultisigHDWallet.fromJson(key);
|
||||
break;
|
||||
case HDAezeedWallet.type:
|
||||
unserializedWallet = HDAezeedWallet.fromJson(key);
|
||||
break;
|
||||
case LightningCustodianWallet.type: {
|
||||
/** @type {LightningCustodianWallet} */
|
||||
unserializedWallet = LightningCustodianWallet.fromJson(key);
|
||||
|
|
|
@ -13,6 +13,7 @@ export * from './wallets/hd-segwit-bech32-wallet';
|
|||
export * from './wallets/placeholder-wallet';
|
||||
export * from './wallets/hd-legacy-electrum-seed-p2pkh-wallet';
|
||||
export * from './wallets/hd-segwit-electrum-seed-p2wpkh-wallet';
|
||||
export * from './wallets/hd-aezeed-wallet';
|
||||
export * from './wallets/multisig-hd-wallet';
|
||||
export * from './hd-segwit-bech32-transaction';
|
||||
export * from './multisig-cosigner';
|
||||
|
|
|
@ -10,6 +10,7 @@ import { SegwitBech32Wallet } from './wallets/segwit-bech32-wallet';
|
|||
import { HDLegacyElectrumSeedP2PKHWallet } from './wallets/hd-legacy-electrum-seed-p2pkh-wallet';
|
||||
import { HDSegwitElectrumSeedP2WPKHWallet } from './wallets/hd-segwit-electrum-seed-p2wpkh-wallet';
|
||||
import { MultisigHDWallet } from './wallets/multisig-hd-wallet';
|
||||
import { HDAezeedWallet } from "./wallets/hd-aezeed-wallet";
|
||||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
export default class WalletGradient {
|
||||
|
@ -23,6 +24,7 @@ export default class WalletGradient {
|
|||
static multisigHdWallet = ['#1ce6eb', '#296fc5', '#3500A2'];
|
||||
static defaultGradients = ['#c65afb', '#9053fe'];
|
||||
static lightningCustodianWallet = ['#f1be07', '#f79056'];
|
||||
static aezeedWallet = ['#550271', '#530140'];
|
||||
|
||||
static createWallet = () => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
|
@ -65,6 +67,9 @@ export default class WalletGradient {
|
|||
case MultisigHDWallet.type:
|
||||
gradient = WalletGradient.multisigHdWallet;
|
||||
break;
|
||||
case HDAezeedWallet.type:
|
||||
gradient = WalletGradient.aezeedWallet;
|
||||
break;
|
||||
default:
|
||||
gradient = WalletGradient.defaultGradients;
|
||||
break;
|
||||
|
@ -119,6 +124,9 @@ export default class WalletGradient {
|
|||
case LightningCustodianWallet.type:
|
||||
gradient = WalletGradient.lightningCustodianWallet;
|
||||
break;
|
||||
case HDAezeedWallet.type:
|
||||
gradient = WalletGradient.aezeedWallet;
|
||||
break;
|
||||
default:
|
||||
gradient = WalletGradient.defaultGradients;
|
||||
break;
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
SegwitBech32Wallet,
|
||||
HDLegacyElectrumSeedP2PKHWallet,
|
||||
HDSegwitElectrumSeedP2WPKHWallet,
|
||||
HDAezeedWallet,
|
||||
MultisigHDWallet,
|
||||
} from '.';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
|
@ -100,6 +101,7 @@ function WalletImport() {
|
|||
// 2. check if its HDLegacyP2PKHWallet (BIP44)
|
||||
// 3. check if its HDLegacyBreadwalletWallet (no BIP, just "m/0")
|
||||
// 3.1 check HD Electrum legacy
|
||||
// 3.2 check if its AEZEED
|
||||
// 4. check if its Segwit WIF (P2SH)
|
||||
// 5. check if its Legacy WIF
|
||||
// 6. check if its address (watch-only wallet)
|
||||
|
@ -234,6 +236,28 @@ function WalletImport() {
|
|||
}
|
||||
} catch (_) {}
|
||||
|
||||
// is it AEZEED?
|
||||
try {
|
||||
const aezeed = new HDAezeedWallet();
|
||||
aezeed.setSecret(importText);
|
||||
if (await aezeed.validateMnemonicAsync()) {
|
||||
// not fetching txs or balances, fuck it, yolo, life is too short
|
||||
return WalletImport._saveWallet(aezeed);
|
||||
} else {
|
||||
// there is a chance that a password is required
|
||||
if (await aezeed.mnemonicInvalidPassword()) {
|
||||
const password = await prompt(loc.wallets.enter_bip38_password, '', false);
|
||||
if (!password) {
|
||||
// no passord is basically cancel whole aezeed import process
|
||||
throw new Error(loc._.bad_password);
|
||||
}
|
||||
|
||||
const mnemonics = importText.split(':')[0];
|
||||
return WalletImport.processImportText(mnemonics + ':' + password);
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
const hd2 = new HDSegwitP2SHWallet();
|
||||
hd2.setSecret(importText);
|
||||
if (hd2.validateMnemonic()) {
|
||||
|
|
141
class/wallets/hd-aezeed-wallet.js
Normal file
141
class/wallets/hd-aezeed-wallet.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const { CipherSeed } = require('aezeed');
|
||||
|
||||
/**
|
||||
* AEZEED mnemonics support, which is used in LND
|
||||
* Support only BIP84 (native segwit) derivations
|
||||
*
|
||||
* @see https://github.com/lightningnetwork/lnd/tree/master/aezeed
|
||||
* @see https://github.com/bitcoinjs/aezeed
|
||||
* @see https://github.com/lightningnetwork/lnd/issues/4960
|
||||
* @see https://github.com/guggero/chantools/blob/master/doc/chantools_genimportscript.md
|
||||
* @see https://github.com/lightningnetwork/lnd/blob/master/keychain/derivation.go
|
||||
*/
|
||||
export class HDAezeedWallet extends AbstractHDElectrumWallet {
|
||||
static type = 'HDAezeedWallet';
|
||||
static typeReadable = 'HD Aezeed';
|
||||
|
||||
setSecret(newSecret) {
|
||||
this.secret = newSecret.trim();
|
||||
this.secret = this.secret.replace(/[^a-zA-Z0-9:]/g, ' ').replace(/\s+/g, ' ');
|
||||
return this;
|
||||
}
|
||||
|
||||
_getEntropyCached() {
|
||||
if (this._entropyHex) {
|
||||
// cache hit
|
||||
return Buffer.from(this._entropyHex, 'hex');
|
||||
} else {
|
||||
throw new Error('Entropy cache is not filled');
|
||||
}
|
||||
}
|
||||
|
||||
validateMnemonic(): boolean {
|
||||
throw new Error('Use validateMnemonicAsync()');
|
||||
}
|
||||
|
||||
async validateMnemonicAsync() {
|
||||
const [mnemonic3, password] = this.secret.split(':');
|
||||
try {
|
||||
const cipherSeed1 = await CipherSeed.fromMnemonic(mnemonic3, password || 'aezeed');
|
||||
this._entropyHex = cipherSeed1.entropy.toString('hex'); // save cache
|
||||
return !!cipherSeed1.entropy;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async mnemonicInvalidPassword() {
|
||||
const [mnemonic3, password] = this.secret.split(':');
|
||||
try {
|
||||
const cipherSeed1 = await CipherSeed.fromMnemonic(mnemonic3, password || 'aezeed');
|
||||
this._entropyHex = cipherSeed1.entropy.toString('hex'); // save cache
|
||||
} catch (error) {
|
||||
return error.message === 'Invalid Password';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async generate() {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
_getInternalAddressByIndex(index) {
|
||||
index = index * 1; // cast to int
|
||||
if (this.internal_addresses_cache[index]) return this.internal_addresses_cache[index]; // cache hit
|
||||
|
||||
if (!this._node1) {
|
||||
const root = bitcoin.bip32.fromSeed(this._getEntropyCached());
|
||||
const node = root.derivePath("m/84'/0'/0'");
|
||||
this._node1 = node.derive(1);
|
||||
}
|
||||
const address = bitcoin.payments.p2wpkh({
|
||||
pubkey: this._node1.derive(index).publicKey,
|
||||
}).address;
|
||||
|
||||
return (this.internal_addresses_cache[index] = address);
|
||||
}
|
||||
|
||||
_getExternalAddressByIndex(index) {
|
||||
index = index * 1; // cast to int
|
||||
if (this.external_addresses_cache[index]) return this.external_addresses_cache[index]; // cache hit
|
||||
|
||||
if (!this._node0) {
|
||||
const root = bitcoin.bip32.fromSeed(this._getEntropyCached());
|
||||
const node = root.derivePath("m/84'/0'/0'");
|
||||
this._node0 = node.derive(0);
|
||||
}
|
||||
const address = bitcoin.payments.p2wpkh({
|
||||
pubkey: this._node0.derive(index).publicKey,
|
||||
}).address;
|
||||
|
||||
return (this.external_addresses_cache[index] = address);
|
||||
}
|
||||
|
||||
_getWIFByIndex(internal, index) {
|
||||
if (!this.secret) return false;
|
||||
const root = bitcoin.bip32.fromSeed(this._getEntropyCached());
|
||||
const path = `m/84'/0'/0'/${internal ? 1 : 0}/${index}`;
|
||||
const child = root.derivePath(path);
|
||||
|
||||
return child.toWIF();
|
||||
}
|
||||
|
||||
_getNodePubkeyByIndex(node, index) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
getIdentityPubkey() {
|
||||
const root = bitcoin.bip32.fromSeed(this._getEntropyCached());
|
||||
const node = root.derivePath("m/1017'/0'/6'/0/0");
|
||||
|
||||
return node.publicKey.toString('hex');
|
||||
}
|
||||
|
||||
// since its basically a bip84 wallet, we allow all other standard BIP84 features:
|
||||
|
||||
allowSend() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowBatchSend() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSendMax() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowHodlHodlTrading() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowRBF() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowPayJoin() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -87,7 +87,7 @@
|
|||
"offer_promt_fiat": "How much {currency} do you want to buy?",
|
||||
"offer_promt_fiat_e": "For example, 100",
|
||||
"offer_window": "window",
|
||||
"p2p": "A p2p exchange"
|
||||
"p2p": "Buy Bitcoin on a p2p exchange"
|
||||
},
|
||||
"lnd": {
|
||||
"errorInvoiceExpired": "Invoice expired",
|
||||
|
@ -445,6 +445,7 @@
|
|||
"pull_to_refresh": "Pull to Refresh",
|
||||
"warning_do_not_disclose": "Warning! Do not disclose",
|
||||
"add_ln_wallet_first": "You must first add a Lightning wallet.",
|
||||
"identity_pubkey": "Identity Pubkey",
|
||||
"xpub_title": "Wallet XPUB"
|
||||
},
|
||||
"multisig": {
|
||||
|
|
227
package-lock.json
generated
227
package-lock.json
generated
|
@ -6994,6 +6994,15 @@
|
|||
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
|
||||
"dev": true
|
||||
},
|
||||
"aez": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/aez/-/aez-1.0.1.tgz",
|
||||
"integrity": "sha1-5O++9xE6khAvA3VL/fCDgMSw3sg=",
|
||||
"requires": {
|
||||
"blakejs": "^1.1.0",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
|
@ -8146,6 +8155,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"blakejs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
|
||||
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
|
@ -10557,6 +10571,11 @@
|
|||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||
"dev": true
|
||||
},
|
||||
"exit-on-epipe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
||||
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
|
||||
},
|
||||
"expand-brackets": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
|
@ -15825,6 +15844,15 @@
|
|||
"object.assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"junderw-crc32c": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/junderw-crc32c/-/junderw-crc32c-1.2.0.tgz",
|
||||
"integrity": "sha512-tP0w5QOrunUS/XgsDBoZfw2jKNFhnUrdM96IXzuJtCyuXd19Hj47Hfd5+WFd81QDQFosiPffpc/jnSrZ35IV+A==",
|
||||
"requires": {
|
||||
"exit-on-epipe": "~1.0.1",
|
||||
"printj": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
|
@ -16111,16 +16139,58 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
|
||||
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
|
||||
},
|
||||
"lodash.frompairs": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.frompairs/-/lodash.frompairs-4.0.1.tgz",
|
||||
"integrity": "sha1-vE5SB/onV8E25XNhTpZkUGsrG9I="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||
},
|
||||
"lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
|
||||
},
|
||||
"lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
|
||||
},
|
||||
"lodash.pick": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
|
||||
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM="
|
||||
},
|
||||
"lodash.sortby": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
|
||||
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "^3.0.0",
|
||||
"lodash.templatesettings": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.templatesettings": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
|
||||
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
|
@ -18216,6 +18286,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"printj": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
|
||||
},
|
||||
"private": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
|
||||
|
@ -19243,23 +19318,68 @@
|
|||
"from": "git+https://github.com/BlueWallet/react-native-tooltip.git#d369e7ece09e4dec73873f1cfeac83e9d35294a6"
|
||||
},
|
||||
"react-native-vector-icons": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-6.6.0.tgz",
|
||||
"integrity": "sha512-MImKVx8JEvVVBnaShMr7/yTX4Y062JZMupht1T+IEgbqBj4aQeQ1z2SH4VHWKNtWtppk4kz9gYyUiMWqx6tNSw==",
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-7.1.0.tgz",
|
||||
"integrity": "sha512-V2a1zJ4i+kS8O4j183gIwX14St9AxxXabxwYpFBgRhvr2NDXyFcjHDEAgrOYYlt2W57e20aN1tBDU/I+wn9WtQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.0.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"yargs": "^13.2.2"
|
||||
"lodash.frompairs": "^4.0.1",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"lodash.template": "^4.5.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"yargs": "^15.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"cliui": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
|
@ -19267,52 +19387,87 @@
|
|||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"requires": {
|
||||
"p-locate": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.3.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
|
||||
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"requires": {
|
||||
"cliui": "^5.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.1.2"
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
|
@ -19990,6 +20145,10 @@
|
|||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"scryptsy": {
|
||||
"version": "file:blue_modules/scryptsy",
|
||||
"integrity": "sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w=="
|
||||
},
|
||||
"secp256k1": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz",
|
||||
|
|
|
@ -78,11 +78,13 @@
|
|||
"@react-navigation/stack": "5.12.6",
|
||||
"@remobile/react-native-qrcode-local-image": "git+https://github.com/BlueWallet/react-native-qrcode-local-image.git",
|
||||
"@sentry/react-native": "1.9.0",
|
||||
"aez": "1.0.1",
|
||||
"amplitude-js": "7.3.3",
|
||||
"assert": "1.5.0",
|
||||
"base-x": "3.0.8",
|
||||
"bc-bech32": "file:blue_modules/bc-bech32",
|
||||
"bc-ur": "file:blue_modules/bc-ur",
|
||||
"scryptsy": "file:blue_modules/scryptsy",
|
||||
"bech32": "1.1.4",
|
||||
"bignumber.js": "9.0.1",
|
||||
"bip21": "2.0.3",
|
||||
|
@ -106,6 +108,7 @@
|
|||
"eslint-plugin-standard": "4.0.2",
|
||||
"events": "1.1.1",
|
||||
"frisbee": "3.1.4",
|
||||
"junderw-crc32c": "1.2.0",
|
||||
"lottie-ios": "3.1.8",
|
||||
"lottie-react-native": "3.5.0",
|
||||
"metro-react-native-babel-preset": "0.63.0",
|
||||
|
@ -157,7 +160,7 @@
|
|||
"react-native-svg": "12.1.0",
|
||||
"react-native-tcp-socket": "3.7.1",
|
||||
"react-native-tooltip": "git+https://github.com/BlueWallet/react-native-tooltip.git#d369e7ece09e4dec73873f1cfeac83e9d35294a6",
|
||||
"react-native-vector-icons": "6.6.0",
|
||||
"react-native-vector-icons": "7.1.0",
|
||||
"react-native-watch-connectivity": "1.0.3",
|
||||
"react-native-webview": "11.0.0",
|
||||
"react-native-widget-center": "git+https://github.com/BlueWallet/react-native-widget-center.git#e2e9a9038b76d096bf929a87105a97a0a7095001",
|
||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import { ScrollView, View, StyleSheet } from 'react-native';
|
||||
import { BlueSpacing20, SafeBlueArea, BlueCard, BlueText, BlueLoading } from '../BlueComponents';
|
||||
import navigationStyle from '../components/navigationStyle';
|
||||
import { SegwitP2SHWallet, LegacyWallet, HDSegwitP2SHWallet, HDSegwitBech32Wallet } from '../class';
|
||||
import { SegwitP2SHWallet, LegacyWallet, HDSegwitP2SHWallet, HDSegwitBech32Wallet, HDAezeedWallet } from '../class';
|
||||
import { BlueCurrentTheme } from '../components/themes';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const BlueCrypto = require('react-native-blue-crypto');
|
||||
|
@ -63,7 +63,14 @@ export default class Selftest extends Component {
|
|||
// skipping RN-specific test'
|
||||
}
|
||||
|
||||
//
|
||||
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
|
||||
const aezeed = new HDAezeedWallet();
|
||||
aezeed.setSecret('abstract rhythm weird food attract treat mosquito sight royal actor surround ride strike remove guilt catch filter summer mushroom protect poverty cruel chaos pattern');
|
||||
assertStrictEqual(await aezeed.validateMnemonicAsync(), true, 'Aezeed failed');
|
||||
assertStrictEqual(aezeed._getExternalAddressByIndex(0), 'bc1qdjj7lhj9lnjye7xq3dzv3r4z0cta294xy78txn', 'Aezeed failed');
|
||||
} else {
|
||||
// skipping RN-specific test
|
||||
}
|
||||
|
||||
let l = new LegacyWallet();
|
||||
l.setSecret('L4ccWrPMmFDZw4kzAKFqJNxgHANjdy6b7YKNXMwB4xac4FLF3Tov');
|
||||
|
|
|
@ -24,7 +24,15 @@ import { HDLegacyP2PKHWallet } from '../../class/wallets/hd-legacy-p2pkh-wallet'
|
|||
import { HDSegwitP2SHWallet } from '../../class/wallets/hd-segwit-p2sh-wallet';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import Biometric from '../../class/biometrics';
|
||||
import { HDSegwitBech32Wallet, SegwitP2SHWallet, LegacyWallet, SegwitBech32Wallet, WatchOnlyWallet, MultisigHDWallet } from '../../class';
|
||||
import {
|
||||
HDSegwitBech32Wallet,
|
||||
SegwitP2SHWallet,
|
||||
LegacyWallet,
|
||||
SegwitBech32Wallet,
|
||||
WatchOnlyWallet,
|
||||
MultisigHDWallet,
|
||||
HDAezeedWallet,
|
||||
} from '../../class';
|
||||
import { ScrollView } from 'react-native-gesture-handler';
|
||||
import loc from '../../loc';
|
||||
import { useTheme, useRoute, useNavigation } from '@react-navigation/native';
|
||||
|
@ -457,6 +465,13 @@ const WalletDetails = () => {
|
|||
<BlueText>{wallet.getBaseURI()}</BlueText>
|
||||
</>
|
||||
)}
|
||||
|
||||
{wallet.type === HDAezeedWallet.type && (
|
||||
<>
|
||||
<Text style={[styles.textLabel1, stylesHook.textLabel1]}>{loc.wallets.identity_pubkey.toLowerCase()}</Text>
|
||||
<BlueText>{wallet.getIdentityPubkey()}</BlueText>
|
||||
</>
|
||||
)}
|
||||
<>
|
||||
<Text onPress={exportInternals} style={[styles.textLabel2, stylesHook.textLabel2]}>
|
||||
{loc.transactions.list_title.toLowerCase()}
|
||||
|
|
|
@ -31,7 +31,7 @@ describe('BlueWallet UI Tests', () => {
|
|||
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
||||
});
|
||||
|
||||
it('can create wallet, reload app and it persists. then go to receive screen, set custom amount and label.', async () => {
|
||||
it('can create wallet, reload app and it persists. then go to receive screen, set custom amount and label. Dismiss modal and go to WalletsList.', async () => {
|
||||
const lockFile = '/tmp/travislock.' + hashIt(jasmine.currentTest.fullName);
|
||||
if (process.env.TRAVIS) {
|
||||
if (require('fs').existsSync(lockFile))
|
||||
|
@ -512,6 +512,26 @@ describe('BlueWallet UI Tests', () => {
|
|||
'0.00030666 BTC',
|
||||
);
|
||||
|
||||
await element(by.id('ReceiveButton')).tap();
|
||||
try {
|
||||
// in case emulator has no google services and doesnt support pushes
|
||||
// we just dont show this popup
|
||||
await element(by.text(`No, and don't ask me again`)).tap();
|
||||
} catch (_) {}
|
||||
await expect(element(by.id('BitcoinAddressQRCodeContainer'))).toBeVisible();
|
||||
await expect(element(by.text('bc1qtc9zquvq7lgq87kzsgltvv4etwm9uxphfkvkay'))).toBeVisible();
|
||||
await element(by.id('SetCustomAmountButton')).tap();
|
||||
await element(by.id('BitcoinAmountInput')).typeText('1');
|
||||
await element(by.id('CustomAmountDescription')).typeText('Test');
|
||||
await element(by.id('CustomAmountSaveButton')).tap();
|
||||
await expect(element(by.text('1 BTC'))).toBeVisible();
|
||||
await expect(element(by.text('Test'))).toBeVisible();
|
||||
await expect(element(by.id('BitcoinAddressQRCodeContainer'))).toBeVisible();
|
||||
|
||||
|
||||
await expect(element(by.text('bitcoin:bc1qtc9zquvq7lgq87kzsgltvv4etwm9uxphfkvkay?amount=1&label=Test'))).toBeVisible();
|
||||
await device.pressBack();
|
||||
|
||||
await element(by.id('SendButton')).tap();
|
||||
await element(by.text('OK')).tap();
|
||||
|
||||
|
|
70
tests/unit/hd-aezeed.test.js
Normal file
70
tests/unit/hd-aezeed.test.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* global describe, it */
|
||||
import { HDAezeedWallet } from '../../class';
|
||||
const assert = require('assert');
|
||||
|
||||
describe('HDAezeedWallet', () => {
|
||||
it('can import mnemonics and generate addresses and WIFs', async function () {
|
||||
const aezeed = new HDAezeedWallet();
|
||||
|
||||
aezeed.setSecret('bs');
|
||||
assert.ok(!(await aezeed.validateMnemonicAsync()));
|
||||
assert.ok(!(await aezeed.mnemonicInvalidPassword()));
|
||||
|
||||
// correct pass:
|
||||
aezeed.setSecret(
|
||||
'able mix price funny host express lawsuit congress antique float pig exchange vapor drip wide cup style apple tumble verb fix blush tongue market:strongPassword',
|
||||
);
|
||||
assert.ok(await aezeed.validateMnemonicAsync());
|
||||
assert.ok(!(await aezeed.mnemonicInvalidPassword()));
|
||||
|
||||
// no pass but its required:
|
||||
aezeed.setSecret(
|
||||
'able mix price funny host express lawsuit congress antique float pig exchange vapor drip wide cup style apple tumble verb fix blush tongue market',
|
||||
);
|
||||
assert.ok(!(await aezeed.validateMnemonicAsync()));
|
||||
assert.ok(await aezeed.mnemonicInvalidPassword());
|
||||
|
||||
// wrong pass:
|
||||
aezeed.setSecret(
|
||||
'able mix price funny host express lawsuit congress antique float pig exchange vapor drip wide cup style apple tumble verb fix blush tongue market:badpassword',
|
||||
);
|
||||
assert.ok(!(await aezeed.validateMnemonicAsync()));
|
||||
assert.ok(await aezeed.mnemonicInvalidPassword());
|
||||
|
||||
aezeed.setSecret(
|
||||
'able concert slush lend olive cost wagon dawn board robot park snap dignity churn fiction quote shrimp hammer wing jump immune skill sunset west',
|
||||
);
|
||||
assert.ok(await aezeed.validateMnemonicAsync());
|
||||
assert.ok(!(await aezeed.mnemonicInvalidPassword()));
|
||||
|
||||
aezeed.setSecret(
|
||||
'abstract rhythm weird food attract treat mosquito sight royal actor surround ride strike remove guilt catch filter summer mushroom protect poverty cruel chaos pattern',
|
||||
);
|
||||
assert.ok(await aezeed.validateMnemonicAsync());
|
||||
assert.ok(!(await aezeed.mnemonicInvalidPassword()));
|
||||
|
||||
assert.strictEqual(
|
||||
aezeed.getXpub(),
|
||||
'zpub6rrqwqM3aF1Jdz6y5Zw18RTppHbZQeQpsrSyf3E2uibcrsEeZAbm5MX41Nq4XBF7HbCvRVASHLzRkFsg6sMgakcceWzJazZH7SaVPBoXzDQ',
|
||||
);
|
||||
|
||||
let address = aezeed._getExternalAddressByIndex(0);
|
||||
assert.strictEqual(address, 'bc1qdjj7lhj9lnjye7xq3dzv3r4z0cta294xy78txn');
|
||||
assert.ok(aezeed.getAllExternalAddresses().includes('bc1qdjj7lhj9lnjye7xq3dzv3r4z0cta294xy78txn'));
|
||||
|
||||
address = aezeed._getExternalAddressByIndex(1);
|
||||
assert.strictEqual(address, 'bc1qswr3s4fylskqn9vemef8l28qukshuagsjz3wpe');
|
||||
assert.ok(aezeed.getAllExternalAddresses().includes('bc1qswr3s4fylskqn9vemef8l28qukshuagsjz3wpe'));
|
||||
|
||||
address = aezeed._getInternalAddressByIndex(0);
|
||||
assert.strictEqual(address, 'bc1qzyjq8sjj56n8v9fgw5klsc8sq8yuy0jx03hzzp');
|
||||
|
||||
let wif = aezeed._getExternalWIFByIndex(0);
|
||||
assert.strictEqual(wif, 'KxtkgprHVXCcgzRetDt3JnNuRApgzQyRrvAuwiE1yFPjmYnWh6rH');
|
||||
|
||||
wif = aezeed._getInternalWIFByIndex(0);
|
||||
assert.strictEqual(wif, 'L1dewhNXkVMB3JdoXYRikbz6g4CbaMGfSqSXSrmTkk5PvzmEgpdT');
|
||||
|
||||
assert.strictEqual(aezeed.getIdentityPubkey(), '0384b9a7158320e828280075224af324931ca9d6de4334f724dbb553ffee447164');
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue