Use @polkadot/vanitygen (move from page-accounts) (#2431)
* Use @polkadot/vanitygen (move from page-accounts) * Remove vanitygen refs
This commit is contained in:
parent
8acba57b83
commit
3970496892
@ -30,7 +30,6 @@
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
"test": "polkadot-dev-run-test packages/page-claims/src",
|
||||
"vanitygen": "node packages/page-accounts/scripts/vanitygen.js",
|
||||
"start": "yarn clean && cd packages/apps && webpack --config webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -52,7 +51,6 @@
|
||||
"@types/store": "^2.0.2",
|
||||
"@types/styled-components": "^5.0.1",
|
||||
"@types/styled-theming": "^2.2.2",
|
||||
"@types/yargs": "^15.0.4",
|
||||
"i18next-scanner": "^2.11.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
|
||||
@ -1,5 +1 @@
|
||||
# @polkadot/app-accounts
|
||||
|
||||
## vanity
|
||||
|
||||
Running `yarn run vanitygen --match <string>` runs the generator as a Node CLI app. (Orders of a magnitude faster due to the use of libsoldium bindings)
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
"@babel/runtime": "^7.9.0",
|
||||
"@polkadot/react-components": "0.40.0-beta.160",
|
||||
"@polkadot/react-qr": "^0.52.0-beta.17",
|
||||
"@polkadot/vanitygen": "^0.11.0-beta.11",
|
||||
"detect-browser": "^5.0.0",
|
||||
"file-saver": "^2.0.2",
|
||||
"yargs": "^15.3.1"
|
||||
"file-saver": "^2.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const [compiled] = ['../vanitygen/cli.js']
|
||||
.map((file) => path.join(__dirname, file))
|
||||
.filter((file) => fs.existsSync(file));
|
||||
|
||||
if (compiled) {
|
||||
require(compiled);
|
||||
} else {
|
||||
require('@babel/register')({
|
||||
extensions: ['.js', '.ts'],
|
||||
plugins: [
|
||||
['module-resolver', {
|
||||
alias: {}
|
||||
}]
|
||||
]
|
||||
});
|
||||
require('../src/vanitygen/cli.ts');
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, IdentityIcon } from '@polkadot/react-components';
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
@ -19,8 +19,10 @@ interface Props extends BareProps {
|
||||
}
|
||||
|
||||
function Match ({ address, className, count, offset, onCreateToggle, onRemove, seed }: Props): React.ReactElement<Props> {
|
||||
const [hexSeed, setHexSeed] = useState('');
|
||||
|
||||
const hexSeed = useMemo(
|
||||
() => u8aToHex(seed),
|
||||
[seed]
|
||||
);
|
||||
const _onCreate = useCallback(
|
||||
(): void => onCreateToggle(hexSeed),
|
||||
[hexSeed]
|
||||
@ -30,10 +32,6 @@ function Match ({ address, className, count, offset, onCreateToggle, onRemove, s
|
||||
[address]
|
||||
);
|
||||
|
||||
useEffect((): void => {
|
||||
setHexSeed(u8aToHex(seed));
|
||||
}, [seed]);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className='vanity--Match-item'>
|
||||
|
||||
@ -4,19 +4,19 @@
|
||||
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { GeneratorMatches, GeneratorMatch, GeneratorResult } from '../vanitygen/types';
|
||||
import { GeneratorMatches, GeneratorMatch, GeneratorResult } from '@polkadot/vanitygen/types';
|
||||
import { ComponentProps } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, Dropdown, Input, TxComponent } from '@polkadot/react-components';
|
||||
import uiSettings from '@polkadot/ui-settings';
|
||||
import generator from '@polkadot/vanitygen/generator';
|
||||
import matchRegex from '@polkadot/vanitygen/regex';
|
||||
import generatorSort from '@polkadot/vanitygen/sort';
|
||||
|
||||
import CreateModal from '../modals/Create';
|
||||
import translate from '../translate';
|
||||
import generator from '../vanitygen';
|
||||
import matchRegex from '../vanitygen/regex';
|
||||
import generatorSort from '../vanitygen/sort';
|
||||
import Match from './Match';
|
||||
|
||||
interface Props extends ComponentProps, I18nProps {}
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { GeneratorCalculation, GeneratorOptions } from './types';
|
||||
|
||||
const MAX_OFFSET = 5;
|
||||
|
||||
function calculateAtOne (atOffset: number, test: string[], address: string): GeneratorCalculation {
|
||||
return {
|
||||
count: test.reduce((count, c, index): number => {
|
||||
if (index === count) {
|
||||
count += (c === '?' || c === address.charAt(index + atOffset)) ? 1 : 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}, 0),
|
||||
offset: atOffset
|
||||
};
|
||||
}
|
||||
|
||||
function calculateAt (atOffset: number, test: string[][], address: string): GeneratorCalculation {
|
||||
let bestCount = 0;
|
||||
let bestOffset = 1;
|
||||
|
||||
for (let i = 0; i < test.length; i++) {
|
||||
const { count, offset } = calculateAtOne(atOffset, test[i], address);
|
||||
|
||||
if (count > bestCount) {
|
||||
bestCount = count;
|
||||
bestOffset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
count: bestCount,
|
||||
offset: bestOffset
|
||||
};
|
||||
}
|
||||
|
||||
export default function calculate (test: string[][], _address: string, { atOffset = -1, withCase = false }: GeneratorOptions): GeneratorCalculation {
|
||||
const address = withCase
|
||||
? _address
|
||||
: _address.toLowerCase();
|
||||
|
||||
if (atOffset > 0) {
|
||||
return calculateAt(atOffset, test, address);
|
||||
}
|
||||
|
||||
let bestCount = 0;
|
||||
let bestOffset = 1;
|
||||
|
||||
for (let index = 0; index < MAX_OFFSET; index++) {
|
||||
const { count, offset } = calculateAt(index, test, address);
|
||||
|
||||
if (count > bestCount) {
|
||||
bestCount = count;
|
||||
bestOffset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
count: bestCount,
|
||||
offset: bestOffset
|
||||
};
|
||||
}
|
||||
@ -1,133 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { GeneratorOptions } from './types';
|
||||
|
||||
import yargs from 'yargs';
|
||||
import chalk from 'chalk';
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
import generator from '.';
|
||||
import matchRegex from './regex';
|
||||
|
||||
interface Best {
|
||||
address: string;
|
||||
count: number;
|
||||
mnemonic?: string;
|
||||
offset: number;
|
||||
seed?: Uint8Array;
|
||||
withCase?: boolean;
|
||||
}
|
||||
|
||||
const { match, mnemonic, network, type, withCase } = yargs
|
||||
.option('match', {
|
||||
default: 'Test',
|
||||
type: 'string'
|
||||
})
|
||||
.option('mnemonic', {
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
})
|
||||
.option('network', {
|
||||
choices: ['substrate', 'polkadot', 'kusama'],
|
||||
default: 'substrate'
|
||||
})
|
||||
.option('type', {
|
||||
choices: ['ed25519', 'sr25519'],
|
||||
default: 'sr25519'
|
||||
})
|
||||
.option('withCase', {
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
})
|
||||
.argv;
|
||||
|
||||
const INDICATORS = ['|', '/', '-', '\\'];
|
||||
const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g');
|
||||
|
||||
const options: GeneratorOptions = {
|
||||
match,
|
||||
network,
|
||||
runs: 50,
|
||||
type: type as KeypairType,
|
||||
withCase,
|
||||
withHex: !mnemonic
|
||||
};
|
||||
const startAt = Date.now();
|
||||
let best: Best = {
|
||||
address: '',
|
||||
count: -1,
|
||||
offset: 65536
|
||||
};
|
||||
let total = 0;
|
||||
let indicator = -1;
|
||||
const tests = options.match.split(',');
|
||||
|
||||
tests.forEach((test): void => {
|
||||
if (!matchRegex.test(test)) {
|
||||
console.error("Invalid character found in match string, allowed is '1-9' (no '0'), 'A-H, J-N & P-Z' (no 'I' or 'O'), 'a-k & m-z' (no 'l') and '?' (wildcard)");
|
||||
process.exit(-1);
|
||||
}
|
||||
});
|
||||
|
||||
switch (network) {
|
||||
case 'kusama':
|
||||
setSS58Format(2);
|
||||
break;
|
||||
|
||||
case 'polkadot':
|
||||
setSS58Format(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
setSS58Format(42);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(options);
|
||||
|
||||
function showProgress (): void {
|
||||
const elapsed = (Date.now() - startAt) / 1000;
|
||||
|
||||
indicator++;
|
||||
|
||||
if (indicator === INDICATORS.length) {
|
||||
indicator = 0;
|
||||
}
|
||||
|
||||
process.stdout.write(`\r[${INDICATORS[indicator]}] ${(total.toString().match(NUMBER_REGEX) || []).join(',')} keys in ${(elapsed).toFixed(2)}s (${(total / elapsed).toFixed(0)} keys/s)`);
|
||||
}
|
||||
|
||||
function showBest (): void {
|
||||
const { address, count, mnemonic, offset, seed } = best;
|
||||
|
||||
console.log(`\r::: ${address.slice(0, offset)}${chalk.cyan(address.slice(offset, count + offset))}${address.slice(count + offset)} <= ${u8aToHex(seed)} (count=${count}, offset=${offset})${mnemonic ? '\n ' + mnemonic : ''}`);
|
||||
}
|
||||
|
||||
cryptoWaitReady()
|
||||
.then((): void => {
|
||||
while (true) {
|
||||
const nextBest = generator(options).found.reduce((best, match): Best => {
|
||||
if ((match.count > best.count) || ((match.count === best.count) && (match.offset <= best.offset))) {
|
||||
return match;
|
||||
}
|
||||
|
||||
return best;
|
||||
}, best);
|
||||
|
||||
total += options.runs;
|
||||
|
||||
if (nextBest.address !== best.address) {
|
||||
best = nextBest;
|
||||
showBest();
|
||||
showProgress();
|
||||
} else if ((total % (options.withHex ? 1000 : 100)) === 0) {
|
||||
showProgress();
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error: Error): void => console.error(error));
|
||||
@ -1,31 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { GeneratorMatch, GeneratorOptions } from './types';
|
||||
|
||||
import { encodeAddress, mnemonicGenerate, naclKeypairFromSeed, randomAsU8a, schnorrkelKeypairFromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
|
||||
|
||||
import calculate from './calculate';
|
||||
|
||||
export default function generator (test: string[][], options: GeneratorOptions): GeneratorMatch {
|
||||
const mnemonic = options.withHex
|
||||
? undefined
|
||||
: mnemonicGenerate(12);
|
||||
const seed = mnemonic
|
||||
? mnemonicToMiniSecret(mnemonic)
|
||||
: randomAsU8a();
|
||||
const pair = options.type === 'sr25519'
|
||||
? schnorrkelKeypairFromSeed(seed)
|
||||
: naclKeypairFromSeed(seed);
|
||||
const address = encodeAddress(pair.publicKey);
|
||||
const { count, offset } = calculate(test, address, options);
|
||||
|
||||
return {
|
||||
address,
|
||||
count,
|
||||
mnemonic,
|
||||
offset,
|
||||
seed
|
||||
};
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { GeneratorMatches, GeneratorResult, GeneratorOptions } from './types';
|
||||
|
||||
import generate from './generate';
|
||||
|
||||
export default function generator (options: GeneratorOptions): GeneratorResult {
|
||||
const { match, runs = 10, withCase = false } = options;
|
||||
const test = (withCase ? match : match.toLowerCase()).split(',').map((c): string[] => c.split(''));
|
||||
const startAt = Date.now();
|
||||
const found: GeneratorMatches = [];
|
||||
|
||||
while (found.length !== runs) {
|
||||
found.push(generate(test, options));
|
||||
}
|
||||
|
||||
return {
|
||||
elapsed: Date.now() - startAt,
|
||||
found
|
||||
};
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
const regex = new RegExp('^[1-9A-HJ-NP-Za-km-z]*$', '');
|
||||
|
||||
export default regex;
|
||||
@ -1,31 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { GeneratorMatch } from './types';
|
||||
|
||||
function numberSort (a: number, b: number): number {
|
||||
if (a > b) {
|
||||
return -1;
|
||||
} else if (a < b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export default function sort (a: GeneratorMatch, b: GeneratorMatch): number {
|
||||
const countResult = numberSort(a.count, b.count);
|
||||
|
||||
if (countResult !== 0) {
|
||||
return countResult;
|
||||
}
|
||||
|
||||
const positionResult = numberSort(b.offset, a.offset);
|
||||
|
||||
if (positionResult !== 0) {
|
||||
return positionResult;
|
||||
}
|
||||
|
||||
return a.address.localeCompare(b.address);
|
||||
}
|
||||
33
packages/page-accounts/src/vanitygen/types.d.ts
vendored
33
packages/page-accounts/src/vanitygen/types.d.ts
vendored
@ -1,33 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
|
||||
export interface GeneratorCalculation {
|
||||
count: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface GeneratorMatch extends GeneratorCalculation {
|
||||
address: string;
|
||||
mnemonic?: string;
|
||||
seed: Uint8Array;
|
||||
}
|
||||
|
||||
export type GeneratorMatches = GeneratorMatch[];
|
||||
|
||||
export interface GeneratorOptions {
|
||||
atOffset?: number;
|
||||
match: string;
|
||||
network?: string;
|
||||
runs: number;
|
||||
type: KeypairType;
|
||||
withCase?: boolean;
|
||||
withHex?: boolean;
|
||||
}
|
||||
|
||||
export interface GeneratorResult {
|
||||
elapsed: number;
|
||||
found: GeneratorMatches;
|
||||
}
|
||||
21
yarn.lock
21
yarn.lock
@ -2886,9 +2886,9 @@ __metadata:
|
||||
"@babel/runtime": ^7.9.0
|
||||
"@polkadot/react-components": 0.40.0-beta.160
|
||||
"@polkadot/react-qr": ^0.52.0-beta.17
|
||||
"@polkadot/vanitygen": ^0.11.0-beta.11
|
||||
detect-browser: ^5.0.0
|
||||
file-saver: ^2.0.2
|
||||
yargs: ^15.3.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@ -3527,6 +3527,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/vanitygen@npm:^0.11.0-beta.11":
|
||||
version: 0.11.0-beta.11
|
||||
resolution: "@polkadot/vanitygen@npm:0.11.0-beta.11"
|
||||
dependencies:
|
||||
"@babel/core": ^7.9.0
|
||||
"@babel/runtime": ^7.9.0
|
||||
"@polkadot/util": ^2.6.2
|
||||
"@polkadot/util-crypto": ^2.6.2
|
||||
chalk: ^3.0.0
|
||||
yargs: ^15.3.1
|
||||
bin:
|
||||
polkadot-js-vanitygen: index.js
|
||||
checksum: 2/c37a6f919cb31773dcb293af64a71030a0513593d0b137a038b7db52de1af67b9b4eca71762aec234e2e987e01cd6669c39a944e77612e2012c7db86a6b37d7c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@polkadot/wasm-crypto@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@polkadot/wasm-crypto@npm:1.2.1"
|
||||
@ -3968,7 +3984,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/yargs@npm:^15.0.0, @types/yargs@npm:^15.0.4":
|
||||
"@types/yargs@npm:^15.0.0":
|
||||
version: 15.0.4
|
||||
resolution: "@types/yargs@npm:15.0.4"
|
||||
dependencies:
|
||||
@ -18248,7 +18264,6 @@ __metadata:
|
||||
"@types/store": ^2.0.2
|
||||
"@types/styled-components": ^5.0.1
|
||||
"@types/styled-theming": ^2.2.2
|
||||
"@types/yargs": ^15.0.4
|
||||
i18next-scanner: ^2.11.0
|
||||
react: ^16.13.1
|
||||
react-dom: ^16.13.1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user