diff --git a/package.json b/package.json index 40fb7e9be9..b72b764a2c 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/page-accounts/README.md b/packages/page-accounts/README.md index 6adfe80b58..75a8b16640 100644 --- a/packages/page-accounts/README.md +++ b/packages/page-accounts/README.md @@ -1,5 +1 @@ # @polkadot/app-accounts - -## vanity - -Running `yarn run vanitygen --match ` runs the generator as a Node CLI app. (Orders of a magnitude faster due to the use of libsoldium bindings) diff --git a/packages/page-accounts/package.json b/packages/page-accounts/package.json index c01e760d1a..e82dba2ffd 100644 --- a/packages/page-accounts/package.json +++ b/packages/page-accounts/package.json @@ -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" } } diff --git a/packages/page-accounts/scripts/vanitygen.js b/packages/page-accounts/scripts/vanitygen.js deleted file mode 100755 index f1ada41910..0000000000 --- a/packages/page-accounts/scripts/vanitygen.js +++ /dev/null @@ -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'); -} diff --git a/packages/page-accounts/src/Vanity/Match.tsx b/packages/page-accounts/src/Vanity/Match.tsx index c52bcf1889..9a16edddea 100644 --- a/packages/page-accounts/src/Vanity/Match.tsx +++ b/packages/page-accounts/src/Vanity/Match.tsx @@ -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 { - 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 (
diff --git a/packages/page-accounts/src/Vanity/index.tsx b/packages/page-accounts/src/Vanity/index.tsx index 492f0ed6d4..e9abb16d94 100644 --- a/packages/page-accounts/src/Vanity/index.tsx +++ b/packages/page-accounts/src/Vanity/index.tsx @@ -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 {} diff --git a/packages/page-accounts/src/vanitygen/calculate.ts b/packages/page-accounts/src/vanitygen/calculate.ts deleted file mode 100644 index 2b8dbc4903..0000000000 --- a/packages/page-accounts/src/vanitygen/calculate.ts +++ /dev/null @@ -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 - }; -} diff --git a/packages/page-accounts/src/vanitygen/cli.ts b/packages/page-accounts/src/vanitygen/cli.ts deleted file mode 100644 index 798217cd88..0000000000 --- a/packages/page-accounts/src/vanitygen/cli.ts +++ /dev/null @@ -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)); diff --git a/packages/page-accounts/src/vanitygen/generate.ts b/packages/page-accounts/src/vanitygen/generate.ts deleted file mode 100644 index d8b6d66650..0000000000 --- a/packages/page-accounts/src/vanitygen/generate.ts +++ /dev/null @@ -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 - }; -} diff --git a/packages/page-accounts/src/vanitygen/index.ts b/packages/page-accounts/src/vanitygen/index.ts deleted file mode 100644 index 10cbce275f..0000000000 --- a/packages/page-accounts/src/vanitygen/index.ts +++ /dev/null @@ -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 - }; -} diff --git a/packages/page-accounts/src/vanitygen/regex.ts b/packages/page-accounts/src/vanitygen/regex.ts deleted file mode 100644 index 7aacf39a1a..0000000000 --- a/packages/page-accounts/src/vanitygen/regex.ts +++ /dev/null @@ -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; diff --git a/packages/page-accounts/src/vanitygen/sort.ts b/packages/page-accounts/src/vanitygen/sort.ts deleted file mode 100644 index ad32f4d22c..0000000000 --- a/packages/page-accounts/src/vanitygen/sort.ts +++ /dev/null @@ -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); -} diff --git a/packages/page-accounts/src/vanitygen/types.d.ts b/packages/page-accounts/src/vanitygen/types.d.ts deleted file mode 100644 index 7526b53adc..0000000000 --- a/packages/page-accounts/src/vanitygen/types.d.ts +++ /dev/null @@ -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; -} diff --git a/yarn.lock b/yarn.lock index 4db0c45da1..c36cb6e279 100644 --- a/yarn.lock +++ b/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