Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5c6baf425 | ||
|
|
0127899c5e | ||
|
|
f23611cad6 | ||
|
|
a74df109b0 | ||
|
|
9582013bfa | ||
|
|
6c148dcb3b | ||
|
|
65488bbff8 | ||
|
|
40cbb81d1e | ||
|
|
77b896054f | ||
|
|
89c717bd11 | ||
|
|
b22f5643a9 | ||
|
|
8d68ed3117 | ||
|
|
65b1c81c21 | ||
|
|
28cd140cfb | ||
|
|
73b553fbd2 | ||
|
|
f12075798d | ||
|
|
323db21306 | ||
|
|
d54302eacc | ||
|
|
9a98d5b6e4 | ||
|
|
5ec613adf9 | ||
|
|
567ce7955a | ||
|
|
b185dcb072 | ||
|
|
79010f83dc | ||
|
|
5354f93946 | ||
|
|
e787e66ef9 | ||
|
|
440e826fed | ||
|
|
d2e5e1d441 | ||
|
|
32fc32f414 | ||
|
|
0a7b2a7a9f | ||
|
|
c315e6fdaa | ||
|
|
b5d9ed36e1 | ||
|
|
f24c7983c8 | ||
|
|
3447cd40bf | ||
|
|
95f4702e26 | ||
|
|
506142da8a | ||
|
|
34f6eac538 | ||
|
|
ae1a37cdf7 | ||
|
|
fab087bbe5 | ||
|
|
8608098996 | ||
|
|
220f4029b1 | ||
|
|
d21daf1434 | ||
|
|
1a4c16f797 | ||
|
|
975103fd3c | ||
|
|
fb84ac7c25 | ||
|
|
13ae8665d5 | ||
|
|
4e8b2beb0b | ||
|
|
dd1220ac97 |
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: SS58 registry is outdated
|
||||
labels: ci
|
||||
---
|
||||
Discrepancies detected between https://github.com/paritytech/substrate/blob/master/ss58-registry.json and https://github.com/polkadot-js/common/blob/master/packages/networks/src/index.ts
|
||||
|
||||
Check the nightly cron output or run `yarn networks:crosscheck` locally. The output as found from the test includes:
|
||||
@@ -5,7 +5,7 @@ jobs:
|
||||
pr:
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['lint', 'test', 'build', 'docs']
|
||||
step: ['lint', 'test', 'build']
|
||||
name: ${{ matrix.step }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
master:
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['build:release', 'docs:release']
|
||||
step: ['build:release']
|
||||
name: ${{ matrix.step }}
|
||||
if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && github.repository == 'polkadot-js/common'"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -19,7 +19,6 @@ jobs:
|
||||
- name: ${{ matrix.step }}
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
GH_PAGES_SRC: build-docs
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
name: SS58
|
||||
on:
|
||||
schedule:
|
||||
- cron: '45 3 * * *'
|
||||
|
||||
jobs:
|
||||
ss58:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: check
|
||||
env:
|
||||
CI_LOG: 123
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn networks:crosscheck
|
||||
|
||||
- name: issue
|
||||
if: ${{ failure() }}
|
||||
uses: JasonEtco/create-an-issue@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
with:
|
||||
filename: .github/ss58-check.md
|
||||
+52
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -7,5 +7,9 @@ nodeLinker: node-modules
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
|
||||
spec: "@yarnpkg/plugin-version"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-2.2.2.cjs
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 3.6.1 Oct 18, 2020
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add evmToAddress and addressToEvm `@polkadot/util-crypto` (Thanks to https://github.com/jnaviask)
|
||||
- Remove invalid link to docs (thanks to https://github.com/roccomuso)
|
||||
|
||||
Changes:
|
||||
|
||||
- Rename `mnemonicToBip39` to `mnemonicToLegacySeed` (used in non-Substrate compatible fashion)
|
||||
- Update pair signature verification to handle MultiSignature results
|
||||
- Move documentation to docs repo
|
||||
- Added `@polkadot/networks` for a list of known networks and their identifying information
|
||||
|
||||
|
||||
## 3.5.1 Sep 27, 2020
|
||||
|
||||
Contributed:
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
module.exports = {
|
||||
base: '/common/',
|
||||
title: 'polkadot-js/common',
|
||||
description: 'Common utilities and libraries that are in use accross all @polkadot projects',
|
||||
markdown: {
|
||||
lineNumbers: true
|
||||
},
|
||||
themeConfig: {
|
||||
displayAllHeaders: true,
|
||||
nav: [
|
||||
{ text: 'Polkadot/Substrate Apps', link: 'https://polkadot.js.org/apps/' },
|
||||
{ text: 'Project family', link: 'https://polkadot.js.org/' },
|
||||
{
|
||||
text: 'Documentation',
|
||||
items: [
|
||||
{ text: 'API Reference', link: 'https://polkadot.js.org/api/' },
|
||||
{ text: 'Utility Reference (this)', link: 'https://polkadot.js.org/common/' },
|
||||
{ text: 'UI Libs Reference', link: 'https://polkadot.js.org/ui/' },
|
||||
]
|
||||
},
|
||||
{ text: 'GitHub', link: 'https://github.com/polkadot-js/common' }
|
||||
],
|
||||
search: false,
|
||||
sidebar: [
|
||||
{
|
||||
title: 'Examples (keyring)',
|
||||
path: '/examples/keyring/',
|
||||
collapsable: false,
|
||||
sidebarDepth: 1,
|
||||
children: [
|
||||
['/examples/keyring/01_create_account/', 'Create account'],
|
||||
['/examples/keyring/02_load_accounts/', 'Load Accounts']
|
||||
]
|
||||
},
|
||||
['/util/', '@polkadot/util'],
|
||||
['/util-crypto/', '@polkadot/util-crypto'],
|
||||
['/keyring/', '@polkadot/keyring'],
|
||||
'/CONTRIBUTING.md'
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
$accentColor = #fd8824
|
||||
$textColor = #2c3e50
|
||||
|
||||
.home .hero .description,
|
||||
.home .feature h2,
|
||||
.home .feature p {
|
||||
color: $textColor
|
||||
opacity: 0.75
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
home: true
|
||||
heroText:
|
||||
tagline:
|
||||
# Bringing JavaScript to the Polkadot world.
|
||||
# actionText: Repository Overview
|
||||
# actionLink: /REPOS.md
|
||||
features:
|
||||
- title: Keyring
|
||||
details: Manage user keys allowing for signing, encryption and decryption.
|
||||
- title: Utilities
|
||||
details: Various user utilities to work with data and perform check on it.
|
||||
- title: Crypto
|
||||
details: A thin and easy-to-use wrapper around cryptographic and hashing libraries.
|
||||
|
||||
footer: Apache-2 Licensed | Copyright © 2017-2019 polkadot-js authors and contributors
|
||||
---
|
||||
|
||||
## Welcome
|
||||
|
||||
Various useful utility functions that are used across all projects in the [@polkadot](https://polkadot.js.org) namespace. It provides utility functions with additional safety checks, allowing not only for consistent coding, but also reducing the general boilerplate.
|
||||
|
||||
::: tip Examples
|
||||
In a rush and just want examples? [Jump right in](/examples/keyring/) and get a handle on using the various components in your projects.
|
||||
:::
|
||||
|
||||
## Available packages
|
||||
|
||||
It is split up into a number of internal packages, namely utilities -
|
||||
|
||||
- [keyring](keyring/README.md) Keyring management
|
||||
- [util](util/README.md) General utilities
|
||||
- [util-crypto](util-crypto/README.md) Crypto and hashing utilities
|
||||
|
||||
## The Polkadot Project
|
||||
|
||||
You can read more about the Polkadot Network at [https://polkadot.network/](https://polkadot.network/)
|
||||
|
||||
## Github repositories
|
||||
|
||||
You can find the Polkadot repositories at:
|
||||
|
||||
- [https://github.com/polkadot-js](https://github.com/polkadot-js)
|
||||
- [https://github.com/paritytech/polkadot](https://github.com/paritytech/polkadot)
|
||||
- [https://github.com/paritytech/substrate](https://github.com/paritytech/substrate)
|
||||
|
||||
This documentation is generated from [https://github.com/polkadot-js/common](https://github.com/polkadot-js/common)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contribution to Polkadot JS Common are more than welcome. You can [report issues](https://github.com/polkadot-js/common/issues/new) and [log feature requests](https://github.com/polkadot-js/common/issues/new).
|
||||
@@ -1 +0,0 @@
|
||||
yarn.lock
|
||||
@@ -1,5 +0,0 @@
|
||||
# Create Account
|
||||
|
||||
The following example shows how to create and account with keyring.
|
||||
|
||||
<<< @/docs/examples/keyring/01_create_account/index.js
|
||||
@@ -1,22 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
// Import Keyring class and utility function
|
||||
const Keyring = require('@polkadot/keyring').default;
|
||||
const stringToU8a = require('@polkadot/util/string/toU8a').default;
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice
|
||||
const ALICE_SEED = 'Alice'.padEnd(32, ' ');
|
||||
|
||||
// Create an instance of the Keyring
|
||||
const keyring = new Keyring();
|
||||
|
||||
// Create pair and add Alice to keyring pair dictionary (with account seed)
|
||||
const pairAlice = keyring.addFromSeed(stringToU8a(ALICE_SEED));
|
||||
|
||||
console.log(`Created keyring pair for Alice with address: ${keyring.getPair(pairAlice.address).address}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "01_create_account",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to create an account",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.32.10",
|
||||
"@polkadot/keyring": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Load Accounts
|
||||
|
||||
The following example shows how to load all accounts from the keyring as pairs and convert them into JSON format.
|
||||
|
||||
<<< @/docs/examples/keyring/02_load_accounts/index.js
|
||||
@@ -1,34 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
// Import Keyring class and utility function
|
||||
const Keyring = require('@polkadot/keyring').default;
|
||||
const stringToU8a = require('@polkadot/util/string/toU8a').default;
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice and Bob
|
||||
const ALICE_SEED = 'Alice'.padEnd(32, ' ');
|
||||
const BOB_SEED = 'Bob'.padEnd(32, ' ');
|
||||
|
||||
// Create an instance of the Keyring
|
||||
const keyring = new Keyring();
|
||||
|
||||
// Create their pairs with account seeds. Add to keyring pair dictionary
|
||||
keyring.addFromSeed(stringToU8a(ALICE_SEED));
|
||||
keyring.addFromSeed(stringToU8a(BOB_SEED));
|
||||
|
||||
// Note that we did not use `addFromAddress` since it does not add the
|
||||
// secret key to memory so we cannot later retrieve it with `getPairs`
|
||||
|
||||
// Retrieve all keyring pairs from the keyring pair dictionary
|
||||
keyring
|
||||
.getPairs()
|
||||
.forEach((pair, index) => {
|
||||
const { address } = pair;
|
||||
|
||||
console.log(`\nAccount with index #${index} has json: `, JSON.stringify(keyring.toJson(address), null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "02_load_accounts",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to load accounts",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.32.10",
|
||||
"@polkadot/keyring": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Validate Adress
|
||||
|
||||
- This function will return true if the address is a legitamate Polkadot address and false if it is not
|
||||
|
||||
- Works both with Ed25519 and Sr25519 key types
|
||||
@@ -1,24 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
|
||||
const { decodeAddress, encodeAddress } = require('@polkadot/keyring');
|
||||
const { hexToU8a, isHex } = require('@polkadot/util');
|
||||
|
||||
const address = '5GrpknVvGGrGH3EFuURXeMrWHvbpj3VfER1oX5jFtuGbfzCE';
|
||||
|
||||
const isValidAddressPolkadotAddress = () => {
|
||||
try {
|
||||
encodeAddress(
|
||||
isHex(address)
|
||||
? hexToU8a(address)
|
||||
: decodeAddress(address)
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const isValid = isValidAddressPolkadotAddress();
|
||||
|
||||
console.log(isValid);
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "03_validate_address",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to validate a polkadot address",
|
||||
"main": "index.js",
|
||||
"author": "Jesse",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/keyring": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
# Keyring Examples
|
||||
|
||||
Here you will find a list of examples that takes you through the basics of connecting to a local node, retrieving data from the Node and chain and execute transactions on the chain.
|
||||
|
||||
## Running the examples
|
||||
|
||||
From within each folder run the following to install required dependencies and to execute the example:
|
||||
```shell
|
||||
yarn;
|
||||
yarn start
|
||||
```
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Encrypt & Decrypt Message using NaCl
|
||||
|
||||
The following example shows how to encrypt and decrypt a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,27 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
const { naclDecrypt, naclEncrypt } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
const secret = new Uint8Array(32);
|
||||
const messagePreEncryption = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
||||
const noncePreEncryption = new Uint8Array(24);
|
||||
|
||||
// Encrypt the message
|
||||
const { encrypted, nonce } = naclEncrypt(messagePreEncryption, secret, noncePreEncryption);
|
||||
|
||||
// Show contents of the encrypted message
|
||||
console.log(`Encrypted message: ${JSON.stringify(encrypted, null, 2)}`);
|
||||
|
||||
// Decrypt the message
|
||||
const messageDecrypted = naclDecrypt(encrypted, nonce, secret);
|
||||
// Convert each Uint8Array to a string for comparison
|
||||
const isMatch = messagePreEncryption.toString === messageDecrypted.toString;
|
||||
|
||||
// Verify that the decrypted message matches the original message
|
||||
console.log(`Does the decrypted message match the original message? ${isMatch}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "01_encrypt_decrypt_message_nacl",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to encrypt and decrypt a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Sign & Verify Message using NaCl
|
||||
|
||||
The following example shows how to sign and verify a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,33 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
const { stringToU8a, u8aToHex } = require('@polkadot/util');
|
||||
const { naclEncrypt, naclKeypairFromSeed, naclSign, naclVerify, randomAsU8a } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice as fallback if generated mnemonic not valid
|
||||
const seedAlice = 'Alice'.padEnd(32, ' ');
|
||||
|
||||
// Generate new public/secret keypair for Alice from the supplied seed
|
||||
const { publicKey, secretKey } = naclKeypairFromSeed(stringToU8a(seedAlice));
|
||||
|
||||
// Encrypt message. Create Uint8Array's filled with random bytes of specified length
|
||||
const secret = randomAsU8a(32);
|
||||
const messagePreEncryption = stringToU8a('please send me DOTs');
|
||||
const noncePreEncryption = randomAsU8a(24);
|
||||
|
||||
const { encrypted } = naclEncrypt(messagePreEncryption, secret, noncePreEncryption);
|
||||
|
||||
// Sign the message with a valid signature
|
||||
const messageSignature = naclSign(encrypted, secretKey);
|
||||
|
||||
console.log(`Message signature: ${u8aToHex(messageSignature)}`);
|
||||
|
||||
// Validate that the message was correctly signed
|
||||
const isValidSignature = naclVerify(encrypted, messageSignature, publicKey);
|
||||
|
||||
console.log(`Was the message correctly signed? ${isValidSignature}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "02_sign_verify_message_nacl",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to sign and verify a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Create & Generate Mnemonic using BIP39
|
||||
|
||||
The following example shows how to create and generate mnemonics using BIP39.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,29 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
const { mnemonicGenerate, mnemonicToSeed, mnemonicValidate, naclKeypairFromSeed } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
// Create mnemonic string for Alice using BIP39
|
||||
const mnemonicAlice = mnemonicGenerate();
|
||||
|
||||
console.log(`Generated mnemonic: ${mnemonicAlice}`);
|
||||
|
||||
// Validate the mnemic string that was generated
|
||||
const isValidMnemonic = mnemonicValidate(mnemonicAlice);
|
||||
|
||||
console.log(`isValidMnemonic: ${isValidMnemonic}`);
|
||||
|
||||
// Create valid seed from mnemonic as u8a and convert it to a string
|
||||
// FIXME - Replace with mnemonicToSeed once exposed
|
||||
const seedAlice = mnemonicToSeed(mnemonicAlice);
|
||||
|
||||
// Generate new public/secret keypair for Alice from the supplied seed
|
||||
const { publicKey, secretKey } = naclKeypairFromSeed(seedAlice);
|
||||
|
||||
// Encrypt, Sign and Validate the message. See Example 'Sign & Verify Message'
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "03_mnemonic_generate_validate_bip39",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to sign and verify a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Generate a Multisig Account
|
||||
|
||||
Substrate provides a multisig dispatch function in its
|
||||
[Utility pallet](https://crates.parity.io/pallet_utility/index.html). This example generates the
|
||||
address that would correspond to a set of addresses and threshold.
|
||||
@@ -1,40 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
import { createKeyMulti, encodeAddress, sortAddresses } from '@polkadot/util-crypto';
|
||||
|
||||
const SS58Prefix = 0;
|
||||
|
||||
// Input the addresses that will make up the multisig account.
|
||||
const addresses = [
|
||||
'1nUC7afqmo7zwRFWxDjrUQu9skk6fk99pafb4SiyGSRc8z3',
|
||||
'1ZX2XntfLEHrBPy73DpfQp9rG7pbLyvrFjEpi7mNKQgyga5',
|
||||
'14b1kB7CrqzRUeMsKc26FJ73f8FCpxAX6sNieu9gfYSfJuoL'
|
||||
];
|
||||
|
||||
// The number of accounts that must approve. Must be greater than 0 and less than
|
||||
// or equal to the total number of addresses.
|
||||
const threshold = 2;
|
||||
|
||||
// The address (as index in `addresses`) that will submit a transaction.
|
||||
const index = 0;
|
||||
|
||||
function main () {
|
||||
// Address as a byte array.
|
||||
const multiAddress = createKeyMulti(addresses, threshold);
|
||||
|
||||
// Convert byte array to SS58 encoding.
|
||||
const Ss58Address = encodeAddress(multiAddress, SS58Prefix);
|
||||
|
||||
console.log(`\nMultisig Address: ${Ss58Address}`);
|
||||
|
||||
// Take addresses and remove the sender.
|
||||
const otherSignatories = addresses.filter((who) => who !== addresses[index]);
|
||||
|
||||
// Sort them by public key.
|
||||
const otherSignatoriesSorted = sortAddresses(otherSignatories, SS58Prefix);
|
||||
|
||||
console.log(`\nOther Signatories: ${otherSignatoriesSorted}\n`);
|
||||
|
||||
process.exit();
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "04_generate_multisig_address",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to generate a multisig address for Substrate's Utility pallet",
|
||||
"main": "index.js",
|
||||
"author": "joepetrowski",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^2.9.0-beta.1"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
# Util-Crypto Examples
|
||||
|
||||
Here you will find a list of examples that takes you through the basics of encrypting and decrypting messages using NaCl, signing a message with a seed and verifying it using NaCl, and generating and validating mnemonics for account seeds.
|
||||
|
||||
## Running the examples
|
||||
|
||||
From within each folder run the following to install required dependencies and to execute the example:
|
||||
```shell
|
||||
yarn;
|
||||
yarn start
|
||||
```
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.3 KiB |
@@ -6,12 +6,14 @@ const config = require('@polkadot/dev/config/jest');
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleNameMapper: {
|
||||
'@polkadot/keyring(.*)$': '<rootDir>/packages/keyring/src/$1',
|
||||
'@polkadot/networks(.*)$': '<rootDir>/packages/networks/src/$1',
|
||||
'@polkadot/util-(crypto)(.*)$': '<rootDir>/packages/util-$1/src/$2',
|
||||
// eslint-disable-next-line sort-keys
|
||||
'@polkadot/util(.*)$': '<rootDir>/packages/util/src/$1'
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/keyring/build',
|
||||
'<rootDir>/packages/networks/build',
|
||||
'<rootDir>/packages/util/build',
|
||||
'<rootDir>/packages/util-crypto/build'
|
||||
],
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
"publish": {
|
||||
"allowBranch": "master"
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "3.5.1"
|
||||
}
|
||||
+7
-11
@@ -13,22 +13,18 @@
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-ts",
|
||||
"build:release": "polkadot-ci-ghact-build",
|
||||
"docs": "polkadot-dev-build-docs",
|
||||
"docs:release": "polkadot-ci-ghact-docs",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"networks:crosscheck": "polkadot-dev-run-test packages/networks/src/crosscheck",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
"test": "polkadot-dev-run-test --coverage --runInBand",
|
||||
"test": "polkadot-dev-run-test --coverage --runInBand --testPathIgnorePatterns crosscheck",
|
||||
"test:one": "polkadot-dev-run-test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@polkadot/dev": "^0.55.54",
|
||||
"@polkadot/ts": "^0.3.47",
|
||||
"@types/jest": "^26.0.14",
|
||||
"typedoc": "^0.19.2",
|
||||
"typedoc-plugin-markdown": "^3.0.2",
|
||||
"typedoc-plugin-no-inherit": "^1.2.0"
|
||||
"@babel/core": "^7.12.3",
|
||||
"@polkadot/dev": "^0.58.3",
|
||||
"@polkadot/ts": "^0.3.49",
|
||||
"@types/jest": "^26.0.14"
|
||||
},
|
||||
"version": "3.5.1"
|
||||
"version": "3.6.1"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,3 @@ Classes and Functions can be imported as follows:
|
||||
```js
|
||||
import Keyring from '@polkadot/keyring';
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
[Utilities](SUMMARY.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/keyring",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.1",
|
||||
"description": "Keyring management",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -27,8 +27,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/util": "3.5.1",
|
||||
"@polkadot/util-crypto": "3.5.1"
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/util": "3.6.1",
|
||||
"@polkadot/util-crypto": "3.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,16 @@ describe('keypair', (): void => {
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -150,6 +160,16 @@ describe('keypair', (): void => {
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -245,6 +265,16 @@ describe('keypair', (): void => {
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(addressKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -300,6 +330,20 @@ describe('keypair', (): void => {
|
||||
const signature = signer.sign(MESSAGE);
|
||||
|
||||
expect(verifier.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(verifier.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
|
||||
it('allows for signing/verification (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('just some test message');
|
||||
const signer = keyring.createFromUri(PHRASE);
|
||||
const verifier = keyring.addFromJson(
|
||||
JSON.parse('{"address":"KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou","encoded":"U8qFEaghhmNV2PgFhjqzmhyUy37Ok7abfFU2MNsBd0sAgAAAAQAAAAgAAAA3+NniKogzNphiMNueB1X0sGA07B6CaXWfpXPx45iSXoTTprwzU5mOoSqUWO0GKHROI72LN+uJ8Yfv6Ll6JOOV3VPKfoVoFmYm+zDrrMPa0gk5E5kUuSijxADcE6zUrliPVr0Ix/qaghu5SJ7RtWDQLBf4Hp86SJ8Gg6gTSSk=","encoding":{"content":["pkcs8","ethereum"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{}}')
|
||||
);
|
||||
|
||||
const signature = signer.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(verifier.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(verifier.verify(new Uint8Array(), signature)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { KeypairType, Keypair } from '@polkadot/util-crypto/types';
|
||||
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$JsonEncodingTypes, KeyringPair$Meta, KeyringOptions } from './types';
|
||||
|
||||
import { assert, hexToU8a, isHex, isUndefined, stringToU8a } from '@polkadot/util';
|
||||
import { base64Decode, decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed, mnemonicToBip39, mnemonicToMiniSecret } from '@polkadot/util-crypto';
|
||||
import { base64Decode, decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed, mnemonicToLegacySeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
|
||||
|
||||
import { DEV_PHRASE } from './defaults';
|
||||
import createPair from './pair';
|
||||
@@ -183,7 +183,7 @@ export default class Keyring implements KeyringInstance {
|
||||
|
||||
if ([12, 15, 18, 21, 24].includes(parts.length)) {
|
||||
seed = type === 'ethereum'
|
||||
? mnemonicToBip39(phrase)
|
||||
? mnemonicToLegacySeed(phrase)
|
||||
: mnemonicToMiniSecret(phrase, password);
|
||||
} else {
|
||||
assert(str.length <= 32, 'specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
|
||||
|
||||
@@ -6,7 +6,7 @@ import { KeyringPair, KeyringPair$Json, KeyringPair$JsonEncodingTypes, KeyringPa
|
||||
import { PairInfo } from './types';
|
||||
|
||||
import { assert, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
import { blake2AsU8a, ethereumEncode, keccakAsU8a, keyExtractPath, keyFromPath, naclKeypairFromSeed as naclFromSeed, naclSign, naclVerify, schnorrkelKeypairFromSeed as schnorrkelFromSeed, schnorrkelSign, schnorrkelVerify, secp256k1Expand, secp256k1KeypairFromSeed as secp256k1FromSeed, secp256k1Sign, secp256k1Verify, secp256k1Compress } from '@polkadot/util-crypto';
|
||||
import { blake2AsU8a, ethereumEncode, keccakAsU8a, keyExtractPath, keyFromPath, naclKeypairFromSeed as naclFromSeed, naclSign, schnorrkelKeypairFromSeed as schnorrkelFromSeed, schnorrkelSign, secp256k1Expand, secp256k1KeypairFromSeed as secp256k1FromSeed, secp256k1Sign, secp256k1Compress, signatureVerify } from '@polkadot/util-crypto';
|
||||
|
||||
import decode from './decode';
|
||||
import encode from './encode';
|
||||
@@ -47,13 +47,6 @@ const TYPE_ADDRESS = {
|
||||
sr25519: (p: Uint8Array) => p
|
||||
};
|
||||
|
||||
const TYPE_VERIFY = {
|
||||
ecdsa: (m: Uint8Array, s: Uint8Array, p: Uint8Array) => secp256k1Verify(m, s, TYPE_ADDRESS.ecdsa(p), 'blake2'),
|
||||
ed25519: naclVerify,
|
||||
ethereum: (m: Uint8Array, s: Uint8Array, p: Uint8Array) => secp256k1Verify(m, s, TYPE_ADDRESS.ethereum(p), 'keccak', true),
|
||||
sr25519: schnorrkelVerify
|
||||
};
|
||||
|
||||
function isEmpty (u8a: Uint8Array): boolean {
|
||||
return u8a.reduce((count, u8) => count + u8, 0) === 0;
|
||||
}
|
||||
@@ -185,6 +178,6 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
|
||||
return toJson(type, { address, meta }, recode(passphrase), !!passphrase);
|
||||
},
|
||||
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
|
||||
TYPE_VERIFY[type](message, signature, publicKey)
|
||||
signatureVerify(message, signature, TYPE_ADDRESS[type](publicKey), type === 'ethereum').isValid
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,5 @@
|
||||
# @polkadot/networks
|
||||
|
||||
A list of all available Substrate networks and their applicable prefixes.
|
||||
|
||||
This list is periodically checked against the master list available at https://github.com/paritytech/substrate/blob/master/ss58-registry.json
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "@polkadot/networks",
|
||||
"version": "3.6.1",
|
||||
"description": "A list of all available Substrate networks and their applicable prefixes",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/common.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"Keyring",
|
||||
"ed25519"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [
|
||||
"Jaco Greeff <jacogr@gmail.com>"
|
||||
],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/common/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/util": "3.6.1",
|
||||
"@polkadot/x-fetch": "^0.3.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2017-2020 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Ss58Registry } from './types';
|
||||
|
||||
import fs from 'fs';
|
||||
import fetch from '@polkadot/x-fetch';
|
||||
|
||||
import { all } from './';
|
||||
|
||||
const ORIGINAL = 'https://raw.githubusercontent.com/paritytech/substrate/master/ss58-registry.json';
|
||||
const OUTPUT = './.github/ss58-check.md';
|
||||
|
||||
function assertAndLog (check: boolean, error: string): void {
|
||||
if (!check) {
|
||||
process.env.CI_LOG && fs.appendFileSync(OUTPUT, `
|
||||
|
||||
${error}
|
||||
`);
|
||||
|
||||
throw new Error(error);
|
||||
}
|
||||
}
|
||||
|
||||
describe('check latest Substrate ss58 registry', (): void => {
|
||||
let original: Ss58Registry;
|
||||
|
||||
beforeAll(async (): Promise<void> => {
|
||||
original = (await (await fetch(ORIGINAL)).json()) as Ss58Registry;
|
||||
});
|
||||
|
||||
it('has the same number as the original', (): void => {
|
||||
assertAndLog(all.length === original.registry.length, `Number of entries mismatched:: Expected ${original.registry.length} found ${all.length}`);
|
||||
});
|
||||
|
||||
it('has no missing any entries', (): void => {
|
||||
const missing = original.registry
|
||||
.filter(({ prefix }) => !all.some((n) => n.prefix === prefix))
|
||||
.map(({ displayName, prefix }) => `${displayName} (${prefix})`);
|
||||
|
||||
assertAndLog(!missing.length, `Missing entries found: ${JSON.stringify(missing, null, 2)}`);
|
||||
});
|
||||
|
||||
it('has no extra entries', (): void => {
|
||||
const missing = all
|
||||
.filter(({ prefix }) => !original.registry.some((n) => n.prefix === prefix))
|
||||
.map(({ displayName, prefix }) => `${displayName} (${prefix})`);
|
||||
|
||||
assertAndLog(!missing.length, `Extra entries found: ${JSON.stringify(missing, null, 2)}`);
|
||||
});
|
||||
|
||||
it('has the same values as the original', (): void => {
|
||||
const fields = Object.keys(original.schema);
|
||||
const errors = original.registry
|
||||
.map((n): [string, string[]] => {
|
||||
const other = all.find(({ prefix }) => prefix === n.prefix);
|
||||
|
||||
return [
|
||||
`${n.displayName} (${n.prefix})`,
|
||||
other
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
? fields.filter((f) => JSON.stringify(n[f]) !== JSON.stringify(other[f]))
|
||||
: []
|
||||
];
|
||||
})
|
||||
.filter(([, fields]) => fields.length);
|
||||
|
||||
assertAndLog(!errors.length, `Mismatches found: ${JSON.stringify(errors.map(([name, m]) => `${name}:: ${m.join(', ')}`), null, 2)}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2020 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import filtered from './';
|
||||
|
||||
describe('filtered', (): void => {
|
||||
it('has the correct starting order', (): void => {
|
||||
expect(filtered.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,396 @@
|
||||
// Copyright 2017-2020 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Network, NetworkFromSubstrate } from './types';
|
||||
|
||||
// These are known prefixes that are not sorted
|
||||
const UNSORTED = [0, 2, 42];
|
||||
|
||||
// NOTE: In the case where the network was hard-spooned and multiple genesisHashes
|
||||
// are provided, it needs to be in reverse order, i.e. most-recent first, oldest
|
||||
// last. This make lookups for the current a simple genesisHash[0]
|
||||
// (See Kusama as an example)
|
||||
|
||||
const all: NetworkFromSubstrate[] = [
|
||||
{
|
||||
decimals: [10],
|
||||
displayName: 'Polkadot Relay Chain',
|
||||
genesisHash: ['0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'],
|
||||
icon: 'polkadot',
|
||||
network: 'polkadot',
|
||||
prefix: 0,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['DOT'],
|
||||
website: 'https://polkadot.network'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'This prefix is reserved.',
|
||||
network: 'reserved1',
|
||||
prefix: 1,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'Kusama Relay Chain',
|
||||
genesisHash: [
|
||||
'0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe', // Kusama CC3,
|
||||
'0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2
|
||||
'0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' // Kusama CC1
|
||||
],
|
||||
icon: 'polkadot',
|
||||
network: 'kusama',
|
||||
prefix: 2,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['KSM'],
|
||||
website: 'https://kusama.network'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'This prefix is reserved.',
|
||||
network: 'reserved3',
|
||||
prefix: 3,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Katal Chain',
|
||||
network: 'katalchain',
|
||||
prefix: 4,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Plasm Network',
|
||||
genesisHash: ['0x3e86364d4b4894021cb2a0390bcf2feb5517d5292f2de2bb9404227e908b0b8b'],
|
||||
network: 'plasm',
|
||||
prefix: 5,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['PLM'],
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'Bifrost',
|
||||
network: 'bifrost',
|
||||
prefix: 6,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['BNC'],
|
||||
website: 'https://bifrost.finance/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Edgeware',
|
||||
genesisHash: ['0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b'],
|
||||
network: 'edgeware',
|
||||
prefix: 7,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['EDG'],
|
||||
website: 'https://edgewa.re'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Acala Karura Canary',
|
||||
network: 'karura',
|
||||
prefix: 8,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['KAR'],
|
||||
website: 'https://acala.network/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Laminar Reynolds Canary',
|
||||
network: 'reynolds',
|
||||
prefix: 9,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['REY'],
|
||||
website: 'http://laminar.network/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Acala',
|
||||
network: 'acala',
|
||||
prefix: 10,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['ACA'],
|
||||
website: 'https://acala.network/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Laminar',
|
||||
network: 'laminar',
|
||||
prefix: 11,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['LAMI'],
|
||||
website: 'http://laminar.network/'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Polymath',
|
||||
network: 'polymath',
|
||||
prefix: 12,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'SubstraTEE',
|
||||
network: 'substratee',
|
||||
prefix: 13,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: 'https://www.substratee.com'
|
||||
},
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'Kulupu',
|
||||
genesisHash: ['0xf7a99d3cb92853d00d5275c971c132c074636256583fee53b3bbe60d7b8769ba'],
|
||||
network: 'kulupu',
|
||||
prefix: 16,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['KLP'],
|
||||
website: 'https://kulupu.network/'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Dark Mainnet',
|
||||
network: 'dark',
|
||||
prefix: 17,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [9, 9],
|
||||
displayName: 'Darwinia Network',
|
||||
network: 'darwinia',
|
||||
prefix: 18,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['RING', 'KTON'],
|
||||
website: 'https://darwinia.network/'
|
||||
},
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'GeekCash',
|
||||
network: 'geek',
|
||||
prefix: 19,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['GEEK'],
|
||||
website: 'https://geekcash.org'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Stafi',
|
||||
genesisHash: ['0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80'],
|
||||
network: 'stafi',
|
||||
prefix: 20,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [6],
|
||||
displayName: 'Dock Testnet',
|
||||
genesisHash: ['0x3f0608444cf5d7eec977430483ffef31ff86dfa6bfc6d7114023ee80cc03ea3f'],
|
||||
network: 'dock-testnet',
|
||||
prefix: 21,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['DCK'],
|
||||
website: 'https://dock.io'
|
||||
},
|
||||
{
|
||||
decimals: [6],
|
||||
displayName: 'Dock Mainnet',
|
||||
genesisHash: ['0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9'],
|
||||
network: 'dock-mainnet',
|
||||
prefix: 22,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['DCK'],
|
||||
website: 'https://dock.io'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'ShiftNrg',
|
||||
network: 'shift',
|
||||
prefix: 23,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'ZERO',
|
||||
network: 'zero',
|
||||
prefix: 24,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['PLAY'],
|
||||
website: 'https://zero.io'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'ZERO Alphaville',
|
||||
network: 'zero-alphaville',
|
||||
prefix: 25,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['PLAY'],
|
||||
website: 'https://zero.io'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Subsocial',
|
||||
genesisHash: ['0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8'],
|
||||
network: 'subsocial',
|
||||
prefix: 28,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Phala Network',
|
||||
network: 'phala',
|
||||
prefix: 30,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Robonomics Network',
|
||||
network: 'robonomics',
|
||||
prefix: 32,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'DataHighway',
|
||||
network: 'datahighway',
|
||||
prefix: 33,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Centrifuge Chain',
|
||||
network: 'centrifuge',
|
||||
prefix: 36,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['RAD'],
|
||||
website: 'https://centrifuge.io/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'Nodle Chain',
|
||||
network: 'nodle',
|
||||
prefix: 37,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['NODL'],
|
||||
website: 'https://nodle.io/'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'MathChain mainnet',
|
||||
network: 'mathchain',
|
||||
prefix: 39,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['MATH'],
|
||||
website: 'https://mathwallet.org'
|
||||
},
|
||||
{
|
||||
decimals: [18],
|
||||
displayName: 'MathChain testnet',
|
||||
network: 'mathchain-testnet',
|
||||
prefix: 40,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['MATH'],
|
||||
website: 'https://mathwallet.org'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'Substrate',
|
||||
network: 'substrate',
|
||||
prefix: 42,
|
||||
standardAccount: '*25519',
|
||||
symbols: null,
|
||||
website: 'https://substrate.dev/'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'This prefix is reserved.',
|
||||
network: 'reserved43',
|
||||
prefix: 43,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: [8],
|
||||
displayName: 'ChainX',
|
||||
network: 'chainx',
|
||||
prefix: 44,
|
||||
standardAccount: '*25519',
|
||||
symbols: ['PCX'],
|
||||
website: 'https://chainx.org/'
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'This prefix is reserved.',
|
||||
network: 'reserved46',
|
||||
prefix: 46,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'This prefix is reserved.',
|
||||
network: 'reserved47',
|
||||
prefix: 47,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
},
|
||||
{
|
||||
decimals: null,
|
||||
displayName: 'All prefixes 48 and higher are reserved and cannot be allocated.',
|
||||
network: 'reserved48',
|
||||
prefix: 48,
|
||||
standardAccount: null,
|
||||
symbols: null,
|
||||
website: null
|
||||
}
|
||||
];
|
||||
|
||||
// The list of available/claimed prefixes
|
||||
// - we only include those where we have a standardAccount
|
||||
// - when no icon has been specified, default to substrate
|
||||
// - sort by name, however we keep 0, 2, 42 first in the list
|
||||
const available: Network[] = all
|
||||
.filter((n) => n.standardAccount === '*25519')
|
||||
.map((n) => ({ ...n, genesisHash: n.genesisHash || [], icon: n.icon || 'substrate' }))
|
||||
.sort((a, b) =>
|
||||
UNSORTED.includes(a.prefix) && UNSORTED.includes(b.prefix)
|
||||
? 0
|
||||
: UNSORTED.includes(a.prefix)
|
||||
? -1
|
||||
: UNSORTED.includes(b.prefix)
|
||||
? 1
|
||||
: a.displayName.localeCompare(b.displayName)
|
||||
);
|
||||
|
||||
// A filtered list of those chains we have details about (genesisHashes)
|
||||
const filtered: Network[] = available.filter((n) => n.genesisHash.length || n.prefix === 42);
|
||||
|
||||
export { all, available };
|
||||
|
||||
export default filtered;
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate';
|
||||
|
||||
export interface NetworkFromSubstrate {
|
||||
decimals: number[] | null,
|
||||
displayName: string;
|
||||
network: string;
|
||||
prefix: number;
|
||||
genesisHash?: string[] | null;
|
||||
icon?: Icon | null;
|
||||
standardAccount: '*25519' | null;
|
||||
symbols: string[] | null;
|
||||
website: string | null;
|
||||
}
|
||||
|
||||
export interface Network extends NetworkFromSubstrate {
|
||||
genesisHash: string[];
|
||||
icon: Icon;
|
||||
}
|
||||
|
||||
export interface Ss58Registry {
|
||||
registry: NetworkFromSubstrate[];
|
||||
specification: string;
|
||||
schema: Record<string, string>;
|
||||
}
|
||||
@@ -15,7 +15,3 @@ Functions can be imported as follows:
|
||||
```js
|
||||
import { mnemonicGenerate } from '@polkadot/util-crypto';
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
[Utilities](SUMMARY.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/util-crypto",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.1",
|
||||
"description": "A collection of useful crypto utilities for @polkadot",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -25,8 +25,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/util": "3.5.1",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/networks": "3.6.1",
|
||||
"@polkadot/util": "3.6.1",
|
||||
"@polkadot/wasm-crypto": "^1.4.1",
|
||||
"base-x": "^3.0.8",
|
||||
"bip39": "^3.0.2",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { hexToU8a } from '@polkadot/util';
|
||||
|
||||
import addressToEvm from './addressToEvm';
|
||||
|
||||
describe('addressToEvm', (): void => {
|
||||
it('creates a valid known EVM address', (): void => {
|
||||
expect(
|
||||
addressToEvm('KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou')
|
||||
).toEqual(hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee9'));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import decode from './decode';
|
||||
|
||||
/**
|
||||
* @name addressToEvm
|
||||
* @summary Converts an SS58 address to its corresponding EVM address.
|
||||
*/
|
||||
export default function addressToEvm (address: string | Uint8Array, ignoreChecksum?: boolean): Uint8Array {
|
||||
const decoded = decode(address, ignoreChecksum);
|
||||
|
||||
return decoded.subarray(0, 20);
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { allowedSS58 } from './ss58';
|
||||
import { available } from '@polkadot/networks';
|
||||
|
||||
const defaults = {
|
||||
allowedDecodedLengths: [1, 2, 4, 8, 32, 33],
|
||||
// publicKey has prefix + 2 checksum bytes, short only prefix + 1 checksum byte
|
||||
allowedEncodedLengths: [3, 4, 6, 10, 35, 36],
|
||||
allowedPrefix: allowedSS58,
|
||||
allowedPrefix: available.map(({ prefix }) => prefix),
|
||||
prefix: 42
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import evmToAddress from './evmToAddress';
|
||||
|
||||
describe('evmToAddress', (): void => {
|
||||
it('creates a valid known SS58 address', (): void => {
|
||||
expect(
|
||||
evmToAddress('0xd43593c715fdd31c61141abd04a99fd6822c8558', 42, 'blake2')
|
||||
).toEqual('5FrLxJsyJ5x9n2rmxFwosFraxFCKcXZDngRLNectCn64UjtZ');
|
||||
});
|
||||
|
||||
it('fails when length is invalid', (): void => {
|
||||
expect(
|
||||
() => evmToAddress('0x1234567890ABCDEF1234567890ABCDEF')
|
||||
).toThrow(/address length/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import encode from './encode';
|
||||
import { Prefix } from './types';
|
||||
|
||||
import hasher from '../secp256k1/hasher';
|
||||
import { HashType } from '../secp256k1/types';
|
||||
|
||||
import { u8aConcat } from '@polkadot/util';
|
||||
|
||||
/**
|
||||
* @name evmToAddress
|
||||
* @summary Converts an EVM address to its corresponding SS58 address.
|
||||
*/
|
||||
export default function evmToAddress (evmAddress: string | Uint8Array, ss58Format?: Prefix, hashType: HashType = 'blake2'): string {
|
||||
const wrapError = (message: string) => `Converting ${evmAddress as string}: ${message}`;
|
||||
|
||||
const message = u8aConcat('evm:', evmAddress);
|
||||
|
||||
if (message.length !== 24) {
|
||||
throw new Error(wrapError('Invalid evm address length'));
|
||||
}
|
||||
|
||||
const address = hasher(hashType, message);
|
||||
|
||||
return encode(address, ss58Format);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import addressToEvm from './addressToEvm';
|
||||
import checkAddress from './check';
|
||||
import checkAddressChecksum from './checkChecksum';
|
||||
import createKeyMulti from './keyMulti';
|
||||
@@ -10,12 +11,14 @@ import deriveAddress from './derive';
|
||||
import encodeAddress from './encode';
|
||||
import encodeDerivedAddress from './encodeDerived';
|
||||
import encodeMultiAddress from './encodeMulti';
|
||||
import evmToAddress from './evmToAddress';
|
||||
import addressEq from './eq';
|
||||
import setSS58Format from './setSS58Format';
|
||||
import sortAddresses from './sort';
|
||||
|
||||
export {
|
||||
addressEq,
|
||||
addressToEvm,
|
||||
checkAddress,
|
||||
checkAddressChecksum,
|
||||
createKeyDerived,
|
||||
@@ -25,6 +28,7 @@ export {
|
||||
encodeAddress,
|
||||
encodeDerivedAddress,
|
||||
encodeMultiAddress,
|
||||
evmToAddress,
|
||||
setSS58Format,
|
||||
sortAddresses
|
||||
};
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export const allowedSS58 = [
|
||||
// Polkadot
|
||||
0, 1,
|
||||
// Kusama
|
||||
2, 3,
|
||||
// Katal Chain
|
||||
4,
|
||||
// Kulupu
|
||||
16, 17,
|
||||
// Dothereum
|
||||
20,
|
||||
// Dock testnet and mainnet
|
||||
21, 22,
|
||||
// Substrate default
|
||||
42, 43,
|
||||
// Substrate BBQ (deprecated)
|
||||
68, 69
|
||||
];
|
||||
@@ -6,8 +6,8 @@ import '../polyfill';
|
||||
/**
|
||||
* @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds
|
||||
*/
|
||||
export { default as mnemonicToBip39 } from './toBip39';
|
||||
export { default as mnemonicGenerate } from './generate';
|
||||
export { default as mnemonicToEntropy } from './toEntropy';
|
||||
export { default as mnemonicToLegacySeed } from './toLegacySeed';
|
||||
export { default as mnemonicToMiniSecret } from './toMiniSecret';
|
||||
export { default as mnemonicValidate } from './validate';
|
||||
|
||||
+4
-4
@@ -4,13 +4,13 @@
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { waitReady } from '@polkadot/wasm-crypto';
|
||||
|
||||
import { mnemonicToBip39 } from './';
|
||||
import { mnemonicToLegacySeed } from './';
|
||||
|
||||
describe('mnemonicToBip39Seed', (): void => {
|
||||
describe('mnemonicToLegacySeed', (): void => {
|
||||
it('generates a valid seed', (): void => {
|
||||
expect(
|
||||
u8aToHex(
|
||||
mnemonicToBip39('seed sock milk update focus rotate barely fade car face mechanic mercy')
|
||||
mnemonicToLegacySeed('seed sock milk update focus rotate barely fade car face mechanic mercy')
|
||||
)
|
||||
).toEqual('0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027');
|
||||
});
|
||||
@@ -20,7 +20,7 @@ describe('mnemonicToBip39Seed', (): void => {
|
||||
|
||||
expect(
|
||||
u8aToHex(
|
||||
mnemonicToBip39('seed sock milk update focus rotate barely fade car face mechanic mercy')
|
||||
mnemonicToLegacySeed('seed sock milk update focus rotate barely fade car face mechanic mercy')
|
||||
)
|
||||
).toEqual('0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027');
|
||||
});
|
||||
+1
-1
@@ -23,7 +23,7 @@ import { bip39ToSeed, isReady } from '@polkadot/wasm-crypto';
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export default function toBip39 (mnemonic: string, password = ''): Uint8Array {
|
||||
export default function toLegacy (mnemonic: string, password = ''): Uint8Array {
|
||||
return isReady()
|
||||
? bip39ToSeed(mnemonic, password)
|
||||
: bufferToU8a(mnemonicToSeedSync(mnemonic, password)).subarray(0, 32);
|
||||
@@ -10,32 +10,33 @@ import naclVerify from '../nacl/verify';
|
||||
import schnorrkelVerify from '../schnorrkel/verify';
|
||||
import secp256k1Verify from '../secp256k1/verify';
|
||||
|
||||
const VERIFIERS: [KeypairType, (message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string) => boolean][] = [
|
||||
['ed25519', naclVerify],
|
||||
['sr25519', schnorrkelVerify],
|
||||
type Verifier = [KeypairType, (message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) => boolean];
|
||||
|
||||
const VERIFIERS_ECDSA: Verifier[] = [
|
||||
[
|
||||
'ecdsa',
|
||||
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string) =>
|
||||
secp256k1Verify(message, signature, publicKey, 'blake2')
|
||||
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) =>
|
||||
secp256k1Verify(message, signature, publicKey, 'blake2', isExpanded)
|
||||
],
|
||||
[
|
||||
'ethereum',
|
||||
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string) =>
|
||||
secp256k1Verify(message, signature, publicKey, 'keccak')
|
||||
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) =>
|
||||
secp256k1Verify(message, signature, publicKey, 'keccak', isExpanded)
|
||||
]
|
||||
];
|
||||
|
||||
const CRYPTO_TYPES: KeypairType[] = [
|
||||
'ed25519',
|
||||
'sr25519',
|
||||
'ecdsa',
|
||||
'ethereum'
|
||||
const VERIFIERS: Verifier[] = [
|
||||
['ed25519', naclVerify],
|
||||
['sr25519', schnorrkelVerify],
|
||||
...VERIFIERS_ECDSA
|
||||
];
|
||||
|
||||
function verifyDetect (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array): VerifyResult {
|
||||
result.isValid = VERIFIERS.some(([crypto, verify]): boolean => {
|
||||
const CRYPTO_TYPES: ('ed25519' | 'sr25519' | 'ecdsa')[] = ['ed25519', 'sr25519', 'ecdsa'];
|
||||
|
||||
function verifyDetect (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean, verifiers = VERIFIERS): VerifyResult {
|
||||
result.isValid = verifiers.some(([crypto, verify]): boolean => {
|
||||
try {
|
||||
if (verify(message, signature, publicKey)) {
|
||||
if (verify(message, signature, publicKey, isExpanded)) {
|
||||
result.crypto = crypto;
|
||||
|
||||
return true;
|
||||
@@ -50,19 +51,20 @@ function verifyDetect (result: VerifyResult, message: Uint8Array | string, signa
|
||||
return result;
|
||||
}
|
||||
|
||||
function verifyMultisig (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array): VerifyResult {
|
||||
function verifyMultisig (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean): VerifyResult {
|
||||
assert([0, 1, 2].includes(signature[0]), `Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`);
|
||||
|
||||
result.crypto = CRYPTO_TYPES[signature[0]] || 'none';
|
||||
const type = CRYPTO_TYPES[signature[0]] || 'none';
|
||||
|
||||
result.crypto = type;
|
||||
|
||||
try {
|
||||
result.isValid = {
|
||||
ecdsa: (): boolean => secp256k1Verify(message, signature.subarray(1), publicKey, 'blake2'),
|
||||
ed25519: (): boolean => naclVerify(message, signature.subarray(1), publicKey),
|
||||
ethereum: (): boolean => secp256k1Verify(message, signature.subarray(1), publicKey, 'keccak'),
|
||||
none: (): boolean => { throw Error('no verify for `none` crypto type'); },
|
||||
sr25519: (): boolean => schnorrkelVerify(message, signature.subarray(1), publicKey)
|
||||
}[result.crypto]();
|
||||
ecdsa: () => verifyDetect(result, message, signature.subarray(1), publicKey, isExpanded, VERIFIERS_ECDSA).isValid,
|
||||
ed25519: () => naclVerify(message, signature.subarray(1), publicKey),
|
||||
none: () => { throw Error('no verify for `none` crypto type'); },
|
||||
sr25519: () => schnorrkelVerify(message, signature.subarray(1), publicKey)
|
||||
}[type]();
|
||||
} catch (error) {
|
||||
// ignore, result.isValid still set to false
|
||||
}
|
||||
@@ -70,18 +72,15 @@ function verifyMultisig (result: VerifyResult, message: Uint8Array | string, sig
|
||||
return result;
|
||||
}
|
||||
|
||||
export default function signatureVerify (message: Uint8Array | string, signature: Uint8Array | string, addressOrPublicKey: Uint8Array | string): VerifyResult {
|
||||
export default function signatureVerify (message: Uint8Array | string, signature: Uint8Array | string, addressOrPublicKey: Uint8Array | string, isExpanded?: boolean): VerifyResult {
|
||||
const signatureU8a = u8aToU8a(signature);
|
||||
|
||||
assert([64, 65, 66].includes(signatureU8a.length), `Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`);
|
||||
|
||||
const result: VerifyResult = { crypto: 'none', isValid: false };
|
||||
const publicKey = addressDecode(addressOrPublicKey);
|
||||
const isMultisig = [0, 1, 2].includes(signatureU8a[0]) && [65, 66].includes(signatureU8a.length);
|
||||
|
||||
if (isMultisig) {
|
||||
return verifyMultisig(result, message, signatureU8a, publicKey);
|
||||
} else {
|
||||
return verifyDetect(result, message, signatureU8a, publicKey);
|
||||
}
|
||||
return [0, 1, 2].includes(signatureU8a[0]) && [65, 66].includes(signatureU8a.length)
|
||||
? verifyMultisig(result, message, signatureU8a, publicKey, isExpanded)
|
||||
: verifyDetect(result, message, signatureU8a, publicKey, isExpanded);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,3 @@ Functions can be imported directly from the package, e.g.
|
||||
```js
|
||||
import { isHex } from '@polkadot/util';
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
[Utilities](SUMMARY.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/util",
|
||||
"version": "3.5.1",
|
||||
"version": "3.6.1",
|
||||
"description": "A collection of useful utilities for @polkadot",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -25,13 +25,13 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@polkadot/x-textdecoder": "^0.3.2",
|
||||
"@polkadot/x-textencoder": "^0.3.2",
|
||||
"@babel/runtime": "^7.12.1",
|
||||
"@polkadot/x-textdecoder": "^0.3.3",
|
||||
"@polkadot/x-textencoder": "^0.3.3",
|
||||
"@types/bn.js": "^4.11.6",
|
||||
"bn.js": "^5.1.3",
|
||||
"camelcase": "^5.3.1",
|
||||
"chalk": "^4.1.0",
|
||||
"ip-regex": "^4.1.0"
|
||||
"ip-regex": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
"paths": {
|
||||
"@polkadot/keyring": [ "packages/keyring/src" ],
|
||||
"@polkadot/keyring/*": [ "packages/keyring/src/*" ],
|
||||
"@polkadot/networks": [ "packages/networks/src" ],
|
||||
"@polkadot/networks/*": [ "packages/networks/src/*" ],
|
||||
"@polkadot/util-crypto": [ "packages/util-crypto/src" ],
|
||||
"@polkadot/util-crypto/*": [ "packages/util-crypto/src/*" ],
|
||||
"@polkadot/util": [ "packages/util/src" ],
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = {
|
||||
exclude: '**/*+(index|e2e|spec).ts',
|
||||
excludeExternals: true,
|
||||
excludeNotExported: true,
|
||||
excludePrivate: true,
|
||||
excludeProtected: true,
|
||||
hideGenerator: true,
|
||||
includeDeclarations: false,
|
||||
module: 'commonjs',
|
||||
moduleResolution: 'node',
|
||||
name: 'Polkadot JS Common',
|
||||
out: 'docs',
|
||||
stripInternal: 'true',
|
||||
theme: 'markdown'
|
||||
};
|
||||
Reference in New Issue
Block a user