Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db8434559e | ||
|
|
eaf9d97ae3 | ||
|
|
3e6d86b768 | ||
|
|
8aab41648e | ||
|
|
4a535c08c7 | ||
|
|
715486d54e | ||
|
|
1073dc14aa | ||
|
|
5cca95e855 | ||
|
|
942b623273 | ||
|
|
eea99656ad | ||
|
|
04b6df9ac5 | ||
|
|
d5132b56de | ||
|
|
1fdc2c8dae | ||
|
|
b6a2693e5f | ||
|
|
8b3687e062 | ||
|
|
3a8429b687 | ||
|
|
26e9b01198 | ||
|
|
76d71d946d | ||
|
|
0ebc7bd374 | ||
|
|
d94c126744 | ||
|
|
86597dcb17 | ||
|
|
1be682827b | ||
|
|
081b6b4f2b | ||
|
|
7dc38e78cf | ||
|
|
dcf214f250 | ||
|
|
2e82528e1b | ||
|
|
090b91910f | ||
|
|
058d197646 | ||
|
|
0fca8904e6 | ||
|
|
0bf7bc416a | ||
|
|
ea08763307 | ||
|
|
5272645abe | ||
|
|
e5373c35c8 | ||
|
|
b73b96e412 | ||
|
|
18d24bf509 | ||
|
|
fe230f143f | ||
|
|
6357c1e040 | ||
|
|
1876efe13e | ||
|
|
9de142b5f6 | ||
|
|
e5cb0ba2b4 | ||
|
|
dba5d3e7b3 | ||
|
|
8ccfecfff8 | ||
|
|
f2e79ffe67 | ||
|
|
e7f595a11f | ||
|
|
770471aef0 | ||
|
|
6b1ff0036e | ||
|
|
fee81b89ac | ||
|
|
c4d5b8e1ae | ||
|
|
5674b1df67 | ||
|
|
5ccb3e85f8 | ||
|
|
785a23433d | ||
|
|
bead42ca5f | ||
|
|
2d2a1a5989 | ||
|
|
db4dde0a57 | ||
|
|
b5d83f8836 | ||
|
|
cdf6cc6096 | ||
|
|
dfd07e04d4 | ||
|
|
f5a3a6fd73 | ||
|
|
51a7263d38 | ||
|
|
e3b11360ab | ||
|
|
b4bed3d801 | ||
|
|
1f8b573d81 | ||
|
|
a0e5d48208 | ||
|
|
6ce32b8039 | ||
|
|
3ee810904e | ||
|
|
ed73a7912b | ||
|
|
4ec2cf9e43 | ||
|
|
38ac05203e | ||
|
|
bb6a2b4468 | ||
|
|
3c9b20e902 | ||
|
|
e1a2ea49cb | ||
|
|
892004563f | ||
|
|
efe4ce8d9d | ||
|
|
f0f561e243 | ||
|
|
56e34586b3 | ||
|
|
667fe8fb17 | ||
|
|
3fd8074877 | ||
|
|
91a2eac220 | ||
|
|
455ae2ccde | ||
|
|
9d43b787fd | ||
|
|
29551e46b0 | ||
|
|
103745f845 | ||
|
|
cd7a32cf1f | ||
|
|
5004d1d79f | ||
|
|
2607203925 | ||
|
|
5abab5bf13 | ||
|
|
a990b4e40f | ||
|
|
997f8f6a51 | ||
|
|
23e055869c | ||
|
|
de85d063a4 | ||
|
|
5964f790b5 | ||
|
|
a767ef68ca | ||
|
|
c096a4981d | ||
|
|
7dcdef17c3 | ||
|
|
ef839a7a42 | ||
|
|
7bf1706994 | ||
|
|
2999987fb0 | ||
|
|
6ba45086b5 | ||
|
|
e3c51d4b6b | ||
|
|
1295c85df3 | ||
|
|
14d66c32de | ||
|
|
b794d22ac4 | ||
|
|
edb62407e2 | ||
|
|
45b040fbf8 | ||
|
|
777b823317 | ||
|
|
c5ef717398 | ||
|
|
98f0933da5 | ||
|
|
493d0df0c1 | ||
|
|
5d8e92f17c | ||
|
|
2ce178cad2 | ||
|
|
9ccac88372 | ||
|
|
0aa441de96 | ||
|
|
78941a3cde | ||
|
|
514570a5fb | ||
|
|
ad2da94408 | ||
|
|
803edbb8cc | ||
|
|
94692cbbb4 | ||
|
|
0a27c23439 | ||
|
|
0a1cfb15ef | ||
|
|
cd494d7de0 |
@@ -1,2 +0,0 @@
|
|||||||
packages/x-noble-hashes/**/*.ts
|
|
||||||
packages/x-noble-secp256k1/**/*.ts
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
const base = require('@polkadot/dev/config/eslint.cjs');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
...base,
|
|
||||||
ignorePatterns: [
|
|
||||||
...base.ignorePatterns
|
|
||||||
],
|
|
||||||
parserOptions: {
|
|
||||||
...base.parserOptions,
|
|
||||||
project: [
|
|
||||||
'./tsconfig.eslint.json'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...base.rules,
|
|
||||||
// this seems very broken atm, false positives
|
|
||||||
'@typescript-eslint/unbound-method': 'off'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -13,13 +13,13 @@ jobs:
|
|||||||
- uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836
|
- uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GH_PAT_BOT }}
|
github-token: ${{ secrets.GH_PAT_BOT }}
|
||||||
issue-lock-inactive-days: '7'
|
issue-inactive-days: '7'
|
||||||
issue-lock-comment: >
|
issue-comment: >
|
||||||
This thread has been automatically locked since there has not been
|
This thread has been automatically locked since there has not been
|
||||||
any recent activity after it was closed. Please open a new issue
|
any recent activity after it was closed. Please open a new issue
|
||||||
if you think you have a related problem or query.
|
if you think you have a related problem or query.
|
||||||
pr-lock-inactive-days: '2'
|
pr-inactive-days: '2'
|
||||||
pr-lock-comment: >
|
pr-comment: >
|
||||||
This pull request has been automatically locked since there
|
This pull request has been automatically locked since there
|
||||||
has not been any recent activity after it was closed.
|
has not been any recent activity after it was closed.
|
||||||
Please open a new issue for related bugs.
|
Please open a new issue for related bugs.
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ jobs:
|
|||||||
- name: ${{ matrix.step }}
|
- name: ${{ matrix.step }}
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
yarn install --immutable | grep -v 'YN0013'
|
yarn install --immutable
|
||||||
yarn ${{ matrix.step }}
|
yarn ${{ matrix.step }}
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ jobs:
|
|||||||
node-version: 'lts/*'
|
node-version: 'lts/*'
|
||||||
- name: ${{ matrix.step }}
|
- name: ${{ matrix.step }}
|
||||||
run: |
|
run: |
|
||||||
yarn install --immutable | grep -v 'YN0013'
|
yarn install --immutable
|
||||||
yarn ${{ matrix.step }}
|
yarn ${{ matrix.step }}
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ enableImmutableInstalls: false
|
|||||||
|
|
||||||
enableProgressBars: false
|
enableProgressBars: false
|
||||||
|
|
||||||
|
logFilters:
|
||||||
|
# Discard any "cannot be found in cache" messages
|
||||||
|
- code: YN0013
|
||||||
|
level: discard
|
||||||
|
|
||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
|
|||||||
@@ -1,5 +1,100 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 12.3.2 Jun 12, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Adjust `SubstrateNetwork` typing with `HexString` genesisHash
|
||||||
|
- Re-export `Constructor<T>` type (deprecated, replaced with `Class<T>`)
|
||||||
|
|
||||||
|
|
||||||
|
## 12.3.1 Jun 11, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Only allow padding characters in base64 strings
|
||||||
|
- Expand typings for keyring meta with known keys
|
||||||
|
- Adjust object index access for stricter tsconfig settings
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.2 Jun 4, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Apply missing count assignment for `for (...)` loops
|
||||||
|
- Remove unused `@types/*` dev dependencies
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
|
||||||
|
|
||||||
|
## 12.2.1 May 13, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Align `u8aToBigInt` tests with `u8aToBn`
|
||||||
|
- Unroll loops on most-frequently used paths for `u8aToBigInt`
|
||||||
|
- Add `module` to `package.json` export map (ESM-only)
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.2 May 1, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Adjust typing for `isChildClass` & `Constructor` usage
|
||||||
|
|
||||||
|
|
||||||
|
## 12.1.1 Apr 29, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Add shareable `identity` & `noop` functions
|
||||||
|
- Flatten `Buffer | Uint8Array` types (as used) to base-only `Uint8Array`
|
||||||
|
- Apply `readonly` specifiers to private class fields where applicable
|
||||||
|
- Adjust compilation output for `__internal__` class fields
|
||||||
|
- Remove unused types from `util`
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
|
||||||
|
|
||||||
|
## 12.0.1 Apr 22, 2023
|
||||||
|
|
||||||
|
Contributed:
|
||||||
|
|
||||||
|
- Add Cere genesisHash (Thanks to https://github.com/shamilkhan)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Swap secp256k1 functionality to `@noble/curves`
|
||||||
|
- Swap ed25519 functionality to `@noble/curves`
|
||||||
|
- Replace `tweetnacl` secretbox usage with slimmer local version
|
||||||
|
- Adjust `isCodec` helper with closer API alignment
|
||||||
|
- Initial steps to multi-language bip39 support
|
||||||
|
- Use Node webcrypto for Node `getRandomValues` support
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
- Drop support for Node 14 (EOL 30 Apr 2023)
|
||||||
|
|
||||||
|
|
||||||
|
## 11.1.3 Apr 1, 2023
|
||||||
|
|
||||||
|
Contributed:
|
||||||
|
|
||||||
|
- Add Bittensor genesisHash (Thanks to https://github.com/camfairchild)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Allow empty string as valid base32/base58/base64 decoder input
|
||||||
|
- Add additional/missing `/*#__PURE__*/` annotations
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
|
||||||
|
|
||||||
|
## 11.1.2 Mar 25, 2023
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Expand error details for invalid publicKeys in secp256k1 compress/expand operations
|
||||||
|
- Expand `@polkadot/hw-ledger` with specific per-method JSDoc
|
||||||
|
- Upgrade dependencies to latest stable versions
|
||||||
|
|
||||||
|
|
||||||
## 11.1.1 Mar 18, 2023
|
## 11.1.1 Mar 18, 2023
|
||||||
|
|
||||||
Contributed:
|
Contributed:
|
||||||
|
|||||||
+4
-2
@@ -1,5 +1,5 @@
|
|||||||
1567 Jaco 11.1.1 (#1771)
|
1627 Jaco 12.3.2 (#1846)
|
||||||
12 Carlo Sala feat(networks): support ledger for pendulum (#1739)
|
13 Carlo Sala feat(networks): add zeitgeist Ledger support (#1840)
|
||||||
9 Antoine Estienne Add eth uri keyring test (#1291)
|
9 Antoine Estienne Add eth uri keyring test (#1291)
|
||||||
6 Amaury Martiny Add tests from Rust (#283)
|
6 Amaury Martiny Add tests from Rust (#283)
|
||||||
5 Jakub Pánik Add HydraDX parachain to genesis (#1583)
|
5 Jakub Pánik Add HydraDX parachain to genesis (#1583)
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
1 amphineko chore: fix typo in versionDetect messages (#941)
|
1 amphineko chore: fix typo in versionDetect messages (#941)
|
||||||
1 Axel Chalon Simplify @polkadot/keyring KeyringPair (#419)
|
1 Axel Chalon Simplify @polkadot/keyring KeyringPair (#419)
|
||||||
1 Brad Larson [FIX] Adjust error message (#646)
|
1 Brad Larson [FIX] Adjust error message (#646)
|
||||||
|
1 Cameron Fairchild Add bittensor details (#1783)
|
||||||
1 Carlos Medeiros add hydradx to knownLedger (#1647)
|
1 Carlos Medeiros add hydradx to knownLedger (#1647)
|
||||||
1 Eliott Teissonniere add nodle ledger specs (#1089)
|
1 Eliott Teissonniere add nodle ledger specs (#1089)
|
||||||
1 Guilane DENGUIR feat(VTB): Added support for VTB blockchain (#1651)
|
1 Guilane DENGUIR feat(VTB): Added support for VTB blockchain (#1651)
|
||||||
@@ -47,6 +48,7 @@
|
|||||||
1 Raymond Zhong Add Edgeware ledger app (#1006)
|
1 Raymond Zhong Add Edgeware ledger app (#1006)
|
||||||
1 Reto Trinkler Adding 4 as address type of ss58 for Katal Chain (#639)
|
1 Reto Trinkler Adding 4 as address type of ss58 for Katal Chain (#639)
|
||||||
1 Rocco Musolino remove doc broken link (#697)
|
1 Rocco Musolino remove doc broken link (#697)
|
||||||
|
1 Shamilkhan Add genesis hash for Cere Network (#1806)
|
||||||
1 Song Zhou Add in ability to encrypt/decrypt msg with keyring (#1070)
|
1 Song Zhou Add in ability to encrypt/decrypt msg with keyring (#1070)
|
||||||
1 Thibaut Sardan add hasLedgerSupport prop to networks (#835)
|
1 Thibaut Sardan add hasLedgerSupport prop to networks (#835)
|
||||||
1 Tomokazu Kozuma fix comment (#1119)
|
1 Tomokazu Kozuma fix comment (#1119)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2017-2023 @polkadot/dev authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import baseConfig from '@polkadot/dev/config/eslint';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
...baseConfig
|
||||||
|
];
|
||||||
+7
-7
@@ -2,7 +2,7 @@
|
|||||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=18.14"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common#readme",
|
"homepage": "https://github.com/polkadot-js/common#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"versions": {
|
"versions": {
|
||||||
"git": "11.1.1",
|
"git": "12.3.2",
|
||||||
"npm": "11.1.1"
|
"npm": "12.3.2"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
@@ -37,10 +37,10 @@
|
|||||||
"test:one": "polkadot-dev-run-test --env browser"
|
"test:one": "polkadot-dev-run-test --env browser"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/dev": "^0.72.15",
|
"@polkadot/dev": "^0.75.19",
|
||||||
"@types/node": "^18.15.3"
|
"@types/node": "^20.3.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"typescript": "^5.0.2"
|
"typescript": "^5.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger-transports#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger-transports#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -14,18 +14,18 @@
|
|||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"browser": "browser.js",
|
"browser": "browser.js",
|
||||||
"main": "node.js",
|
"main": "node.js",
|
||||||
"react-native": "react-native.js",
|
"react-native": "react-native.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ledgerhq/hw-transport": "^6.28.1",
|
"@ledgerhq/hw-transport": "^6.28.4",
|
||||||
"@ledgerhq/hw-transport-webhid": "^6.27.12",
|
"@ledgerhq/hw-transport-webhid": "^6.27.15",
|
||||||
"@ledgerhq/hw-transport-webusb": "^6.27.12",
|
"@ledgerhq/hw-transport-webusb": "^6.27.15",
|
||||||
"@polkadot/util": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"tslib": "^2.5.0"
|
"tslib": "^2.5.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.9"
|
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { Transport, TransportDef } from './types.js';
|
import LedgerHid from '@ledgerhq/hw-transport-webhid';
|
||||||
|
import LedgerUsb from '@ledgerhq/hw-transport-webusb';
|
||||||
|
|
||||||
import LedgerWebHid from '@ledgerhq/hw-transport-webhid';
|
import { createDefs } from './util.js';
|
||||||
import LedgerWebUsb from '@ledgerhq/hw-transport-webusb';
|
|
||||||
|
|
||||||
export { packageInfo } from './packageInfo.js';
|
export { packageInfo } from './packageInfo.js';
|
||||||
|
|
||||||
// See usage of Transport interface in types.ts
|
export const transports = /*#__PURE__*/ createDefs(['webusb', LedgerUsb], ['hid', LedgerHid]);
|
||||||
export const transports: TransportDef[] = [
|
|
||||||
{
|
|
||||||
create: (): Promise<Transport> =>
|
|
||||||
(LedgerWebUsb as unknown as Transport).create(),
|
|
||||||
type: 'webusb'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
create: (): Promise<Transport> =>
|
|
||||||
(LedgerWebHid as unknown as Transport).create(),
|
|
||||||
type: 'hid'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { TransportDef } from './types.js';
|
import { createDefs } from './util.js';
|
||||||
|
|
||||||
export { packageInfo } from './packageInfo.js';
|
export { packageInfo } from './packageInfo.js';
|
||||||
|
|
||||||
export const transports: TransportDef[] = [];
|
export const transports = /*#__PURE__*/ createDefs();
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { Transport, TransportDef } from './types.js';
|
|
||||||
|
|
||||||
import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton';
|
import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton';
|
||||||
|
|
||||||
|
import { createDefs } from './util.js';
|
||||||
|
|
||||||
export { packageInfo } from './packageInfo.js';
|
export { packageInfo } from './packageInfo.js';
|
||||||
|
|
||||||
// See usage of Transport interface in types.ts
|
export const transports = /*#__PURE__*/ createDefs(['hid', LedgerHid]);
|
||||||
export const transports: TransportDef[] = [
|
|
||||||
{
|
|
||||||
create: (): Promise<Transport> =>
|
|
||||||
(LedgerHid as unknown as Transport).create(),
|
|
||||||
type: 'hid'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Do not edit, auto-generated by @polkadot/dev
|
// Do not edit, auto-generated by @polkadot/dev
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '11.1.1' };
|
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '12.3.2' };
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
// CJS, so we use import * syntax
|
||||||
|
import type * as HwTransport from '@ledgerhq/hw-transport';
|
||||||
|
|
||||||
// The actual namespaced Transport interface (as detailed on the next line)
|
// u2f is deprecated an therefore not added
|
||||||
//
|
export type TransportType = 'hid' | 'webusb';
|
||||||
// import type Transport from '@ledgerhq/hw-transport';
|
|
||||||
//
|
export type Transport = HwTransport.default;
|
||||||
// does not quite work on moduleResolution: nodenext, so we just go with a
|
|
||||||
// very light interface here
|
|
||||||
export interface Transport {
|
|
||||||
create (): Promise<Transport>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TransportDef {
|
export interface TransportDef {
|
||||||
/** Create a transport to be used in Ledger operations */
|
/** Create a transport to be used in Ledger operations */
|
||||||
create (): Promise<Transport>;
|
create (): Promise<Transport>;
|
||||||
/** The type of the underlying transport definition */
|
/** The type of the underlying transport definition */
|
||||||
type: LedgerTypes;
|
type: TransportType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import type { Transport, TransportDef, TransportType } from './types.js';
|
||||||
|
|
||||||
|
export function createDefs (...items: readonly [type: TransportType, Clazz: unknown][]): TransportDef[] {
|
||||||
|
return items.map(([type, Clazz]): TransportDef => ({
|
||||||
|
create: (): Promise<Transport> =>
|
||||||
|
(Clazz as Pick<TransportDef, 'create'>).create(),
|
||||||
|
type
|
||||||
|
}));
|
||||||
|
}
|
||||||
@@ -5,6 +5,9 @@
|
|||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/mod.ts"
|
||||||
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../util/tsconfig.build.json" }
|
{ "path": "../util/tsconfig.build.json" }
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -17,13 +17,12 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ledgerhq/hw-transport": "^6.28.1",
|
"@polkadot/hw-ledger-transports": "12.3.2",
|
||||||
"@polkadot/hw-ledger-transports": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"@polkadot/util": "11.1.1",
|
"@zondax/ledger-substrate": "^0.40.7",
|
||||||
"@zondax/ledger-substrate": "^0.40.5",
|
"tslib": "^2.5.3"
|
||||||
"tslib": "^2.5.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { SubstrateApp } from '@zondax/ledger-substrate';
|
import type { SubstrateApp } from '@zondax/ledger-substrate';
|
||||||
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types.js';
|
import type { TransportDef, TransportType } from '@polkadot/hw-ledger-transports/types';
|
||||||
|
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js';
|
||||||
|
|
||||||
import { newSubstrateApp } from '@zondax/ledger-substrate';
|
import { newSubstrateApp } from '@zondax/ledger-substrate';
|
||||||
|
|
||||||
@@ -29,28 +30,38 @@ async function wrapError <T extends WrappedResult> (promise: Promise<T>): Promis
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A very basic wrapper for a ledger app -
|
/**
|
||||||
// - it connects automatically, creating an app as required
|
* @name Ledger
|
||||||
// - Promises return errors (instead of wrapper errors)
|
*
|
||||||
|
* @description
|
||||||
|
* A very basic wrapper for a ledger app -
|
||||||
|
* - it connects automatically on use, creating an underlying interface as required
|
||||||
|
* - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate)
|
||||||
|
*/
|
||||||
export class Ledger {
|
export class Ledger {
|
||||||
|
readonly #ledgerName: string;
|
||||||
|
readonly #transportDef: TransportDef;
|
||||||
|
|
||||||
#app: SubstrateApp | null = null;
|
#app: SubstrateApp | null = null;
|
||||||
|
|
||||||
#chain: Chain;
|
constructor (transport: TransportType, chain: Chain) {
|
||||||
|
const ledgerName = ledgerApps[chain];
|
||||||
|
const transportDef = transports.find(({ type }) => type === transport);
|
||||||
|
|
||||||
#transport: LedgerTypes;
|
if (!ledgerName) {
|
||||||
|
throw new Error(`Unsupported Ledger chain ${chain}`);
|
||||||
constructor (transport: LedgerTypes, chain: Chain) {
|
} else if (!transportDef) {
|
||||||
// u2f is deprecated
|
throw new Error(`Unsupported Ledger transport ${transport}`);
|
||||||
if (!['hid', 'webusb'].includes(transport)) {
|
|
||||||
throw new Error(`Unsupported transport ${transport}`);
|
|
||||||
} else if (!Object.keys(ledgerApps).includes(chain)) {
|
|
||||||
throw new Error(`Unsupported chain ${chain}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#chain = chain;
|
this.#ledgerName = ledgerName;
|
||||||
this.#transport = transport;
|
this.#transportDef = transportDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address associated with a specific account & address offset. Optionally
|
||||||
|
* asks for on-device confirmation
|
||||||
|
*/
|
||||||
public async getAddress (confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerAddress> {
|
public async getAddress (confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerAddress> {
|
||||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
|
return this.withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
|
||||||
const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
|
const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
|
||||||
@@ -62,6 +73,9 @@ export class Ledger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of the Ledger application on the device
|
||||||
|
*/
|
||||||
public async getVersion (): Promise<LedgerVersion> {
|
public async getVersion (): Promise<LedgerVersion> {
|
||||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
|
return this.withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
|
||||||
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion());
|
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion());
|
||||||
@@ -74,6 +88,9 @@ export class Ledger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs a transaction on the Ledger device
|
||||||
|
*/
|
||||||
public async sign (message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerSignature> {
|
public async sign (message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerSignature> {
|
||||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
|
return this.withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
|
||||||
const buffer = u8aToBuffer(message);
|
const buffer = u8aToBuffer(message);
|
||||||
@@ -85,27 +102,21 @@ export class Ledger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getApp (): Promise<SubstrateApp> {
|
/**
|
||||||
if (!this.#app) {
|
* @internal
|
||||||
const def = transports.find(({ type }) => type === this.#transport);
|
*
|
||||||
|
* Returns a created SubstrateApp to perform operations against. Generally
|
||||||
if (!def) {
|
* this is only used internally, to ensure consistent bahavior.
|
||||||
throw new Error(`Unable to find a transport for ${this.#transport}`);
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
const transport = await def.create();
|
|
||||||
|
|
||||||
this.#app = newSubstrateApp(transport, ledgerApps[this.#chain]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.#app;
|
|
||||||
}
|
|
||||||
|
|
||||||
async withApp <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> {
|
async withApp <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const app = await this.getApp();
|
if (!this.#app) {
|
||||||
|
const transport = await this.#transportDef.create();
|
||||||
|
|
||||||
return await fn(app);
|
this.#app = newSubstrateApp(transport, this.#ledgerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fn(this.#app);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.#app = null;
|
this.#app = null;
|
||||||
|
|
||||||
|
|||||||
@@ -38,5 +38,6 @@ export const ledgerApps: Record<string, string> = {
|
|||||||
ternoa: 'Ternoa',
|
ternoa: 'Ternoa',
|
||||||
unique: 'Unique',
|
unique: 'Unique',
|
||||||
vtb: 'VTB',
|
vtb: 'VTB',
|
||||||
xxnetwork: 'XXNetwork'
|
xxnetwork: 'XXNetwork',
|
||||||
|
zeitgeist: 'Zeitgeist'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Do not edit, auto-generated by @polkadot/dev
|
// Do not edit, auto-generated by @polkadot/dev
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '11.1.1' };
|
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '12.3.2' };
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
import type { HexString } from '@polkadot/util/types';
|
import type { HexString } from '@polkadot/util/types';
|
||||||
|
|
||||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
|
||||||
|
|
||||||
export interface AccountOptions {
|
export interface AccountOptions {
|
||||||
/** The index of the account */
|
/** The index of the account */
|
||||||
account: number;
|
account: number;
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/mod.ts"
|
||||||
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../hw-ledger-transports/tsconfig.build.json" },
|
{ "path": "../hw-ledger-transports/tsconfig.build.json" },
|
||||||
{ "path": "../util/tsconfig.build.json" }
|
{ "path": "../util/tsconfig.build.json" }
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "..",
|
||||||
|
"outDir": "./build",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"emitDeclarationOnly": false,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../hw-ledger/tsconfig.build.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"description": "Keyring management",
|
"description": "Keyring management",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -18,15 +18,15 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@polkadot/util": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"@polkadot/util-crypto": "11.1.1",
|
"@polkadot/util-crypto": "12.3.2",
|
||||||
"tslib": "^2.5.0"
|
"tslib": "^2.5.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@polkadot/util": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"@polkadot/util-crypto": "11.1.1"
|
"@polkadot/util-crypto": "12.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { Keyring } from './keyring.js';
|
// all external
|
||||||
|
|
||||||
// eslint-disable-next-line deprecation/deprecation
|
// eslint-disable-next-line deprecation/deprecation
|
||||||
export { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
|
export { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
|
||||||
|
|
||||||
export * from './defaults.js';
|
// all named
|
||||||
|
export { Keyring } from './keyring.js';
|
||||||
export { createPair } from './pair/index.js';
|
|
||||||
export { packageInfo } from './packageInfo.js';
|
export { packageInfo } from './packageInfo.js';
|
||||||
|
export { createPair } from './pair/index.js';
|
||||||
export { createTestKeyring } from './testing.js';
|
export { createTestKeyring } from './testing.js';
|
||||||
export { createTestPairs } from './testingPairs.js';
|
export { createTestPairs } from './testingPairs.js';
|
||||||
|
|
||||||
export { Keyring };
|
// all starred
|
||||||
|
export * from './defaults.js';
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export class Keyring implements KeyringInstance {
|
|||||||
|
|
||||||
readonly #type: KeypairType;
|
readonly #type: KeypairType;
|
||||||
|
|
||||||
#ss58?: number;
|
#ss58?: number | undefined;
|
||||||
|
|
||||||
public decodeAddress = decodeAddress;
|
public decodeAddress = decodeAddress;
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ export class Keyring implements KeyringInstance {
|
|||||||
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
|
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
|
||||||
return this.type === 'ethereum'
|
return this.type === 'ethereum'
|
||||||
? ethereumEncode(address)
|
? ethereumEncode(address)
|
||||||
: encodeAddress(address, ss58Format === undefined ? this.#ss58 : ss58Format);
|
: encodeAddress(address, ss58Format ?? this.#ss58);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Do not edit, auto-generated by @polkadot/dev
|
// Do not edit, auto-generated by @polkadot/dev
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '11.1.1' };
|
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '12.3.2' };
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
export interface PairInfo {
|
export interface PairInfo {
|
||||||
publicKey: Uint8Array;
|
publicKey: Uint8Array;
|
||||||
secretKey?: Uint8Array;
|
secretKey?: Uint8Array | undefined;
|
||||||
seed?: Uint8Array | null;
|
seed?: Uint8Array | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ describe('keyring.addFromUri', (): void => {
|
|||||||
for (const [type, tests] of Object.entries(TESTS)) {
|
for (const [type, tests] of Object.entries(TESTS)) {
|
||||||
const keyring = new Keyring({ type: type as KeypairType });
|
const keyring = new Keyring({ type: type as KeypairType });
|
||||||
|
|
||||||
describe(type, (): void => {
|
describe(`${type}`, (): void => {
|
||||||
tests.forEach(({ pk, ss, uri }): void => {
|
tests.forEach(({ pk, ss, uri }): void => {
|
||||||
it(`creates ${uri}`, (): void => {
|
it(`creates ${uri}`, (): void => {
|
||||||
const pair = keyring.addFromUri(uri, {}, type as KeypairType);
|
const pair = keyring.addFromUri(uri, {}, type as KeypairType);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ describe('testingPairs', (): void => {
|
|||||||
).toEqual(TEST_ADD);
|
).toEqual(TEST_ADD);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checks eth test addresses', (): void => {
|
describe('checks eth test addresses', (): void => {
|
||||||
const ring = createTestPairs({ type: 'ethereum' });
|
const ring = createTestPairs({ type: 'ethereum' });
|
||||||
const keyring = new Keyring({ type: 'ethereum' });
|
const keyring = new Keyring({ type: 'ethereum' });
|
||||||
// priv keys generated by ganache-cli --mnemonic "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
|
// priv keys generated by ganache-cli --mnemonic "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
|
||||||
@@ -62,12 +62,20 @@ describe('testingPairs', (): void => {
|
|||||||
'0x4c42532034540267bf568198ccec4cb822a025da542861fcb146a5fab6433ff8',
|
'0x4c42532034540267bf568198ccec4cb822a025da542861fcb146a5fab6433ff8',
|
||||||
'0x94c49300a58d576011096bcb006aa06f5a91b34b4383891e8029c21dc39fbb8b'];
|
'0x94c49300a58d576011096bcb006aa06f5a91b34b4383891e8029c21dc39fbb8b'];
|
||||||
|
|
||||||
|
// @ts-expect-error We should not delete from the maps, however this is a test
|
||||||
delete ring.nobody;
|
delete ring.nobody;
|
||||||
|
|
||||||
Object.keys(ring).forEach((testKeyring, i) => {
|
Object
|
||||||
if (i < 6) {
|
.keys(ring)
|
||||||
expect(u8aToHex(ring[testKeyring].publicKey)).toEqual(u8aToHex(keyring.createFromUri(privKeys[i]).publicKey));
|
.filter((_, i) => i < 6)
|
||||||
}
|
.forEach((testKeyring, i) => {
|
||||||
});
|
it(`checks #${i}`, (): void => {
|
||||||
|
expect(
|
||||||
|
u8aToHex(ring[testKeyring].publicKey)
|
||||||
|
).toEqual(
|
||||||
|
u8aToHex(keyring.createFromUri(privKeys[i]).publicKey)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,47 @@
|
|||||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||||
import type { KeyringOptions, KeyringPair } from './types.js';
|
import type { KeyringOptions, KeyringPair } from './types.js';
|
||||||
|
|
||||||
import { nobody } from './pair/nobody.js';
|
import { nobody } from './pair/nobody.js';
|
||||||
import { createTestKeyring } from './testing.js';
|
import { createTestKeyring } from './testing.js';
|
||||||
|
|
||||||
export interface TestKeyringMap {
|
export interface TestKeyringMap {
|
||||||
|
nobody: KeyringPair;
|
||||||
|
|
||||||
[index: string]: KeyringPair;
|
[index: string]: KeyringPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTestPairs (options?: KeyringOptions, isDerived = true): TestKeyringMap {
|
export interface TestKeyringMapSubstrate extends TestKeyringMap {
|
||||||
|
alice: KeyringPair;
|
||||||
|
bob: KeyringPair;
|
||||||
|
charlie: KeyringPair;
|
||||||
|
dave: KeyringPair;
|
||||||
|
eve: KeyringPair;
|
||||||
|
ferdie: KeyringPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TestKeyringMapEthereum extends TestKeyringMap {
|
||||||
|
Alith: KeyringPair;
|
||||||
|
Baltathar: KeyringPair;
|
||||||
|
Charleth: KeyringPair;
|
||||||
|
Dorothy: KeyringPair;
|
||||||
|
Ethan: KeyringPair;
|
||||||
|
Faith: KeyringPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DetectMap<O extends KeyringOptions | undefined> = DetectPairType<O> extends 'ethereum'
|
||||||
|
? TestKeyringMapEthereum
|
||||||
|
: TestKeyringMapSubstrate;
|
||||||
|
|
||||||
|
export type DetectPairType<O extends KeyringOptions | undefined> = O extends KeyringOptions
|
||||||
|
? O['type'] extends KeypairType
|
||||||
|
? O['type']
|
||||||
|
: 'sr25519'
|
||||||
|
: 'sr25519';
|
||||||
|
|
||||||
|
export function createTestPairs <O extends KeyringOptions, M = DetectMap<O>> (options?: O, isDerived = true): M {
|
||||||
const keyring = createTestKeyring(options, isDerived);
|
const keyring = createTestKeyring(options, isDerived);
|
||||||
const pairs = keyring.getPairs();
|
const pairs = keyring.getPairs();
|
||||||
const map: TestKeyringMap = { nobody: nobody() };
|
const map: TestKeyringMap = { nobody: nobody() };
|
||||||
@@ -19,5 +50,5 @@ export function createTestPairs (options?: KeyringOptions, isDerived = true): Te
|
|||||||
map[p.meta.name as string] = p;
|
map[p.meta.name as string] = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map as M;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,58 @@ export interface KeyringOptions {
|
|||||||
type?: KeypairType;
|
type?: KeypairType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type KeyringPair$Meta = Record<string, unknown>;
|
export interface KeyringPair$MetaHardware {
|
||||||
|
accountIndex?: number;
|
||||||
|
accountOffset?: number;
|
||||||
|
addressOffset?: number;
|
||||||
|
hardwareType?: 'ledger';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$MetaFlags {
|
||||||
|
isDefaultAuthSelected?: boolean;
|
||||||
|
isExternal?: boolean;
|
||||||
|
isHardware?: boolean;
|
||||||
|
isHidden?: boolean;
|
||||||
|
isInjected?: boolean;
|
||||||
|
isMultisig?: boolean;
|
||||||
|
isProxied?: boolean;
|
||||||
|
isRecent?: boolean;
|
||||||
|
isTesting?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$MetaContract {
|
||||||
|
abi: string;
|
||||||
|
genesisHash?: HexString | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$MetaExtension {
|
||||||
|
source?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$MetaMultisig {
|
||||||
|
threshold?: number;
|
||||||
|
who?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$MetaParent {
|
||||||
|
parentAddress?: string;
|
||||||
|
parentName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KeyringPair$Meta extends KeyringPair$MetaExtension, KeyringPair$MetaFlags, KeyringPair$MetaHardware, KeyringPair$MetaMultisig, KeyringPair$MetaParent {
|
||||||
|
address?: string;
|
||||||
|
contract?: KeyringPair$MetaContract;
|
||||||
|
genesisHash?: HexString | null;
|
||||||
|
name?: string;
|
||||||
|
suri?: string;
|
||||||
|
tags?: string[];
|
||||||
|
type?: KeypairType;
|
||||||
|
whenCreated?: number;
|
||||||
|
whenEdited?: number;
|
||||||
|
whenUsed?: number;
|
||||||
|
|
||||||
|
[key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
export interface KeyringPair$Json extends EncryptedJson {
|
export interface KeyringPair$Json extends EncryptedJson {
|
||||||
/** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */
|
/** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/mod.ts"
|
||||||
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../util/tsconfig.build.json" },
|
{ "path": "../util/tsconfig.build.json" },
|
||||||
{ "path": "../util-crypto/tsconfig.build.json" }
|
{ "path": "../util-crypto/tsconfig.build.json" }
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "..",
|
||||||
|
"outDir": "./build",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"emitDeclarationOnly": false,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../keyring/tsconfig.build.json" },
|
||||||
|
{ "path": "../util/tsconfig.build.json" },
|
||||||
|
{ "path": "../util-crypto/tsconfig.build.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"description": "A list of all available Substrate networks and their applicable prefixes",
|
"description": "A list of all available Substrate networks and their applicable prefixes",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -15,14 +15,14 @@
|
|||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@polkadot/util": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"@substrate/ss58-registry": "^1.39.0",
|
"@substrate/ss58-registry": "^1.40.0",
|
||||||
"tslib": "^2.5.0"
|
"tslib": "^2.5.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/hw-ledger": "11.1.1"
|
"@polkadot/hw-ledger": "12.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,10 +29,16 @@ export const knownGenesis: KnownGenesis = {
|
|||||||
'bifrost-kusama': [
|
'bifrost-kusama': [
|
||||||
'0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed'
|
'0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed'
|
||||||
],
|
],
|
||||||
|
bittensor: [
|
||||||
|
'0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03'
|
||||||
|
],
|
||||||
centrifuge: [
|
centrifuge: [
|
||||||
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
|
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
|
||||||
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
|
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
|
||||||
],
|
],
|
||||||
|
cere: [
|
||||||
|
'0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c'
|
||||||
|
],
|
||||||
composable: [
|
composable: [
|
||||||
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
|
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
|
||||||
],
|
],
|
||||||
@@ -151,5 +157,8 @@ export const knownGenesis: KnownGenesis = {
|
|||||||
],
|
],
|
||||||
xxnetwork: [
|
xxnetwork: [
|
||||||
'0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa'
|
'0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa'
|
||||||
|
],
|
||||||
|
zeitgeist: [
|
||||||
|
'0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060'
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,5 +42,6 @@ export const knownLedger: KnownLedger = {
|
|||||||
ternoa: 0x00003e3,
|
ternoa: 0x00003e3,
|
||||||
unique: 0x00000162,
|
unique: 0x00000162,
|
||||||
vtb: 0x000002b6,
|
vtb: 0x000002b6,
|
||||||
xxnetwork: 0x000007a3
|
xxnetwork: 0x000007a3,
|
||||||
|
zeitgeist: 0x00000162
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ describe('availableNetworks', (): void => {
|
|||||||
expect(availableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]);
|
expect(availableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('has a sorted list (first external, last external)', (): void => {
|
it('has a sorted list (first external, last external)', (): void => {
|
||||||
expect(availableNetworks[3].displayName).toEqual('Acala');
|
expect(availableNetworks[3].displayName).toEqual('3DP network');
|
||||||
expect(availableNetworks[availableNetworks.length - 1].displayName).toEqual('ZERO');
|
expect(availableNetworks[availableNetworks.length - 1].displayName).toEqual('ZERO');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ describe('selectableNetworks', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('has a sorted list (first external, last external)', (): void => {
|
it('has a sorted list (first external, last external)', (): void => {
|
||||||
expect(selectableNetworks[3].displayName).toEqual('Acala');
|
expect(selectableNetworks[3].displayName).toEqual('3DP network');
|
||||||
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('xx network');
|
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('Zeitgeist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Do not edit, auto-generated by @polkadot/dev
|
// Do not edit, auto-generated by @polkadot/dev
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/networks', path: 'auto', type: 'auto', version: '11.1.1' };
|
export const packageInfo = { name: '@polkadot/networks', path: 'auto', type: 'auto', version: '12.3.2' };
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import known from '@substrate/ss58-registry';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
const other = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'packages/networks/src/test/ss58registry.test.json'), 'utf-8')) as unknown;
|
const other = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'packages/networks/test/ss58registry.json'), 'utf-8')) as unknown;
|
||||||
|
|
||||||
describe('@substrate/ss58-registry', (): void => {
|
describe('@substrate/ss58-registry', (): void => {
|
||||||
it('has known values', (): void => {
|
it('has known values', (): void => {
|
||||||
@@ -16,13 +16,13 @@ describe('@substrate/ss58-registry', (): void => {
|
|||||||
try {
|
try {
|
||||||
expect(JSON.parse(json)).toEqual(other);
|
expect(JSON.parse(json)).toEqual(other);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (process.env.GITHUB_REPOSITORY) {
|
if (process.env['GITHUB_REPOSITORY']) {
|
||||||
console.error(json);
|
console.error(json);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(path.join(process.cwd(), 'packages/networks/src/test/ss58registry.test.json'), json, { flag: 'w' });
|
fs.writeFileSync(path.join(process.cwd(), 'packages/networks/test/ss58registry.json'), json, { flag: 'w' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { RegistryEntry } from '@substrate/ss58-registry';
|
import type { RegistryEntry } from '@substrate/ss58-registry';
|
||||||
|
import type { HexString } from '@polkadot/util/types';
|
||||||
|
|
||||||
export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate';
|
export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate';
|
||||||
|
|
||||||
@@ -9,14 +10,14 @@ export type KnownIcon = Record<string, Icon>;
|
|||||||
|
|
||||||
export type KnownLedger = Record<string, number>;
|
export type KnownLedger = Record<string, number>;
|
||||||
|
|
||||||
export type KnownGenesis = Record<string, string[]>;
|
export type KnownGenesis = Record<string, HexString[]>;
|
||||||
|
|
||||||
export type KnownSubstrate = RegistryEntry;
|
export type KnownSubstrate = RegistryEntry;
|
||||||
|
|
||||||
export type KnownTestnet = Record<string, true>;
|
export type KnownTestnet = Record<string, true>;
|
||||||
|
|
||||||
export interface SubstrateNetwork extends KnownSubstrate {
|
export interface SubstrateNetwork extends KnownSubstrate {
|
||||||
genesisHash: string[];
|
genesisHash: HexString[];
|
||||||
hasLedgerSupport: boolean;
|
hasLedgerSupport: boolean;
|
||||||
icon: Icon;
|
icon: Icon;
|
||||||
isIgnored: boolean;
|
isIgnored: boolean;
|
||||||
|
|||||||
+28
-2
@@ -597,7 +597,7 @@
|
|||||||
{
|
{
|
||||||
"prefix": 50,
|
"prefix": 50,
|
||||||
"network": "composable",
|
"network": "composable",
|
||||||
"displayName": "Composable",
|
"displayName": "Composable Finance",
|
||||||
"symbols": [
|
"symbols": [
|
||||||
"LAYR"
|
"LAYR"
|
||||||
],
|
],
|
||||||
@@ -716,7 +716,7 @@
|
|||||||
{
|
{
|
||||||
"prefix": 65,
|
"prefix": 65,
|
||||||
"network": "aventus",
|
"network": "aventus",
|
||||||
"displayName": "AvN Mainnet",
|
"displayName": "Aventus Mainnet",
|
||||||
"symbols": [
|
"symbols": [
|
||||||
"AVT"
|
"AVT"
|
||||||
],
|
],
|
||||||
@@ -1337,6 +1337,19 @@
|
|||||||
"standardAccount": "*25519",
|
"standardAccount": "*25519",
|
||||||
"website": "https://explorer.mainnet.cloudwalk.io"
|
"website": "https://explorer.mainnet.cloudwalk.io"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"prefix": 2021,
|
||||||
|
"network": "logion",
|
||||||
|
"displayName": "logion network",
|
||||||
|
"symbols": [
|
||||||
|
"LGNT"
|
||||||
|
],
|
||||||
|
"decimals": [
|
||||||
|
18
|
||||||
|
],
|
||||||
|
"standardAccount": "*25519",
|
||||||
|
"website": "https://logion.network"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"prefix": 2032,
|
"prefix": 2032,
|
||||||
"network": "interlay",
|
"network": "interlay",
|
||||||
@@ -1640,6 +1653,19 @@
|
|||||||
"standardAccount": "*25519",
|
"standardAccount": "*25519",
|
||||||
"website": "https://ata.network"
|
"website": "https://ata.network"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"prefix": 12155,
|
||||||
|
"network": "impact",
|
||||||
|
"displayName": "Impact Protocol Network",
|
||||||
|
"symbols": [
|
||||||
|
"BSTY"
|
||||||
|
],
|
||||||
|
"decimals": [
|
||||||
|
18
|
||||||
|
],
|
||||||
|
"standardAccount": "*25519",
|
||||||
|
"website": "https://impactprotocol.network/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"prefix": 12191,
|
"prefix": 12191,
|
||||||
"network": "nftmart",
|
"network": "nftmart",
|
||||||
@@ -5,9 +5,10 @@
|
|||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
"include": [
|
"exclude": [
|
||||||
"**/src/**/*.ts",
|
"**/*.spec.ts",
|
||||||
"**/test/*.json"
|
"**/test/*",
|
||||||
|
"**/mod.ts"
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../hw-ledger/tsconfig.build.json" },
|
{ "path": "../hw-ledger/tsconfig.build.json" },
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "..",
|
||||||
|
"outDir": "./build",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"emitDeclarationOnly": false,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../hw-ledger/tsconfig.build.json" },
|
||||||
|
{ "path": "../networks/tsconfig.build.json" },
|
||||||
|
{ "path": "../util/tsconfig.build.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||||
"description": "A collection of useful crypto utilities for @polkadot",
|
"description": "A collection of useful crypto utilities for @polkadot",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -20,25 +20,25 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "11.1.1",
|
"version": "12.3.2",
|
||||||
"browser": {
|
"browser": {
|
||||||
"crypto": false,
|
"crypto": false,
|
||||||
"stream": false
|
"stream": false
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "1.3.0",
|
"@noble/curves": "1.1.0",
|
||||||
"@noble/secp256k1": "1.7.1",
|
"@noble/hashes": "1.3.1",
|
||||||
"@polkadot/networks": "11.1.1",
|
"@polkadot/networks": "12.3.2",
|
||||||
"@polkadot/util": "11.1.1",
|
"@polkadot/util": "12.3.2",
|
||||||
"@polkadot/wasm-crypto": "^7.0.3",
|
"@polkadot/wasm-crypto": "^7.2.1",
|
||||||
"@polkadot/x-bigint": "11.1.1",
|
"@polkadot/wasm-util": "^7.2.1",
|
||||||
"@polkadot/x-randomvalues": "11.1.1",
|
"@polkadot/x-bigint": "12.3.2",
|
||||||
|
"@polkadot/x-randomvalues": "12.3.2",
|
||||||
"@scure/base": "1.1.1",
|
"@scure/base": "1.1.1",
|
||||||
"tslib": "^2.5.0",
|
"tslib": "^2.5.3"
|
||||||
"tweetnacl": "^1.0.3"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@polkadot/util": "11.1.1"
|
"@polkadot/util": "12.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
import { encodeAddress } from './index.js';
|
import { encodeAddress } from './index.js';
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-export
|
||||||
export const ALICE_PUBLIC_SR = new Uint8Array([212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125]);
|
export const ALICE_PUBLIC_SR = new Uint8Array([212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125]);
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-export
|
||||||
export const ALICE_PUBLIC_ED = new Uint8Array([209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79]);
|
export const ALICE_PUBLIC_ED = new Uint8Array([209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79]);
|
||||||
|
|
||||||
const SUBKEY = [
|
const SUBKEY = [
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
export { addressToEvm } from './addressToEvm.js';
|
export { addressToEvm } from './addressToEvm.js';
|
||||||
export { checkAddress } from './check.js';
|
export { checkAddress } from './check.js';
|
||||||
export { checkAddressChecksum } from './checksum.js';
|
export { checkAddressChecksum } from './checksum.js';
|
||||||
export { createKeyMulti } from './keyMulti.js';
|
|
||||||
export { createKeyDerived } from './keyDerived.js';
|
|
||||||
export { decodeAddress } from './decode.js';
|
export { decodeAddress } from './decode.js';
|
||||||
export { deriveAddress } from './derive.js';
|
export { deriveAddress } from './derive.js';
|
||||||
export { encodeAddress } from './encode.js';
|
export { encodeAddress } from './encode.js';
|
||||||
export { encodeDerivedAddress } from './encodeDerived.js';
|
export { encodeDerivedAddress } from './encodeDerived.js';
|
||||||
export { encodeMultiAddress } from './encodeMulti.js';
|
export { encodeMultiAddress } from './encodeMulti.js';
|
||||||
export { evmToAddress } from './evmToAddress.js';
|
|
||||||
export { addressEq } from './eq.js';
|
export { addressEq } from './eq.js';
|
||||||
|
export { evmToAddress } from './evmToAddress.js';
|
||||||
export { isAddress } from './is.js';
|
export { isAddress } from './is.js';
|
||||||
|
export { createKeyDerived } from './keyDerived.js';
|
||||||
|
export { createKeyMulti } from './keyMulti.js';
|
||||||
export { sortAddresses } from './sort.js';
|
export { sortAddresses } from './sort.js';
|
||||||
export { validateAddress } from './validate.js';
|
export { validateAddress } from './validate.js';
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ import { u8aToString } from '@polkadot/util';
|
|||||||
import { base32Decode } from './index.js';
|
import { base32Decode } from './index.js';
|
||||||
|
|
||||||
describe('base32Decode', (): void => {
|
describe('base32Decode', (): void => {
|
||||||
|
it('decodes an empty string)', (): void => {
|
||||||
|
expect(
|
||||||
|
u8aToString(
|
||||||
|
base32Decode('')
|
||||||
|
)
|
||||||
|
).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
it('decodes a base32', (): void => {
|
it('decodes a base32', (): void => {
|
||||||
expect(
|
expect(
|
||||||
u8aToString(
|
u8aToString(
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ interface Config {
|
|||||||
ipfs?: string;
|
ipfs?: string;
|
||||||
regex?: RegExp;
|
regex?: RegExp;
|
||||||
type: string;
|
type: string;
|
||||||
|
withPadding?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array;
|
type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array;
|
||||||
@@ -63,23 +64,26 @@ export function createIs (validate: ValidateFn): ValidateFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function createValidate ({ chars, ipfs, type }: Config): ValidateFn {
|
export function createValidate ({ chars, ipfs, type, withPadding }: Config): ValidateFn {
|
||||||
return (value?: unknown, ipfsCompat?: boolean): value is string => {
|
return (value?: unknown, ipfsCompat?: boolean): value is string => {
|
||||||
if (!value || typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
throw new Error(`Expected non-null, non-empty ${type} string input`);
|
throw new Error(`Expected ${type} string input`);
|
||||||
}
|
} else if (ipfs && ipfsCompat && value[0] !== ipfs) {
|
||||||
|
|
||||||
if (ipfs && ipfsCompat && value[0] !== ipfs) {
|
|
||||||
throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
|
throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
|
for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) {
|
||||||
if (!(chars.includes(value[i]) || (
|
if (chars.includes(value[i])) {
|
||||||
value[i] === '=' && (
|
// all ok, character found
|
||||||
(i === value.length - 1) ||
|
} else if (withPadding && value[i] === '=') {
|
||||||
!chars.includes(value[i + 1])
|
if (i === count - 1) {
|
||||||
)
|
// last character, everything ok
|
||||||
))) {
|
} else if (value[i + 1] === '=') {
|
||||||
|
// next one is also padding, sequence ok
|
||||||
|
} else {
|
||||||
|
throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
|
throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ describe('base32Validate', (): void => {
|
|||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails on empty', (): void => {
|
it('does not fail on empty', (): void => {
|
||||||
expect(
|
expect(
|
||||||
() => base32Validate('')
|
base32Validate('')
|
||||||
).toThrow(/Expected/);
|
).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails on non-string', (): void => {
|
it('fails on non-string', (): void => {
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ import { base32Decode } from '../base32/index.js';
|
|||||||
import { base58Decode } from './index.js';
|
import { base58Decode } from './index.js';
|
||||||
|
|
||||||
describe('base58Encode', (): void => {
|
describe('base58Encode', (): void => {
|
||||||
|
it('decodes an empty string)', (): void => {
|
||||||
|
expect(
|
||||||
|
base58Decode('')
|
||||||
|
).toEqual(new Uint8Array());
|
||||||
|
});
|
||||||
|
|
||||||
it('encodes a base58 to a base32', (): void => {
|
it('encodes a base58 to a base32', (): void => {
|
||||||
expect(
|
expect(
|
||||||
base58Decode('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV')
|
base58Decode('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV')
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
|
import { base58Validate } from './index.js';
|
||||||
|
|
||||||
|
describe('base58Validate', (): void => {
|
||||||
|
it('validates encoded', (): void => {
|
||||||
|
expect(
|
||||||
|
base58Validate('a1UbyspTdnyZXLUQaQbciCxrCWWxz24kgSwGXSQnkbs', false)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on string with extra padding', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base58Validate('a1UbyspTdnyZXLUQaQbciCxrCWWxz24kgSwGXSQnkbs=', false)
|
||||||
|
).toThrow(/Invalid base58 character "="/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -8,7 +8,8 @@ import { createDecode, createEncode, createIs, createValidate } from '../base32/
|
|||||||
const config = {
|
const config = {
|
||||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||||
coder: base64,
|
coder: base64,
|
||||||
type: 'base64'
|
type: 'base64',
|
||||||
|
withPadding: true
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ import { stringToU8a } from '@polkadot/util';
|
|||||||
import { base64Decode } from './index.js';
|
import { base64Decode } from './index.js';
|
||||||
|
|
||||||
describe('base64Decode', (): void => {
|
describe('base64Decode', (): void => {
|
||||||
|
it('decodes an empty string)', (): void => {
|
||||||
|
expect(
|
||||||
|
base64Decode('')
|
||||||
|
).toEqual(
|
||||||
|
stringToU8a('')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('decodes a mixed base64 utf8 string (1)', (): void => {
|
it('decodes a mixed base64 utf8 string (1)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
base64Decode('aGVsbG8gd29ybGQg0J/RgNC40LLQtdGC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
|
base64Decode('aGVsbG8gd29ybGQg0J/RgNC40LLQtdGC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
|
||||||
|
|||||||
@@ -11,4 +11,22 @@ describe('base64Validate', (): void => {
|
|||||||
() => base64Validate('aGVsbG8gd29ybGQg0J/RgNC40LLQtd^GC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
|
() => base64Validate('aGVsbG8gd29ybGQg0J/RgNC40LLQtd^GC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
|
||||||
).toThrow(/Invalid base64 character "\^" \(0x5e\) at index 30/);
|
).toThrow(/Invalid base64 character "\^" \(0x5e\) at index 30/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('validates with one extra padding character', (): void => {
|
||||||
|
expect(
|
||||||
|
base64Validate('bGlnaHQgd28=')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('validates with two extra padding characters', (): void => {
|
||||||
|
expect(
|
||||||
|
base64Validate('bGlnaHQgdw==')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('validates misplaced padding characters', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base64Validate('bGlnaHQgdw=g=')
|
||||||
|
).toThrow(/Invalid base64 padding sequence "=g"/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength: 6
|
|||||||
|
|
||||||
return !hasBigInt || (!onlyJs && isReady())
|
return !hasBigInt || (!onlyJs && isReady())
|
||||||
? blake2b(u8a, u8aToU8a(key), byteLength)
|
? blake2b(u8a, u8aToU8a(key), byteLength)
|
||||||
: blake2bJs(u8a, { dkLen: byteLength, key: key || undefined });
|
: key
|
||||||
|
? blake2bJs(u8a, { dkLen: byteLength, key })
|
||||||
|
: blake2bJs(u8a, { dkLen: byteLength });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name blake2AsHex
|
* @name blake2AsHex
|
||||||
* @description Creates a blake2b hex from the input.
|
* @description Creates a blake2b hex from the input.
|
||||||
*/
|
*/
|
||||||
export const blake2AsHex = createAsHex(blake2AsU8a);
|
export const blake2AsHex = /*#__PURE__*/ createAsHex(blake2AsU8a);
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
import './bundleInit.js';
|
import './bundleInit.js';
|
||||||
|
|
||||||
|
// all named
|
||||||
export { packageInfo } from './packageInfo.js';
|
export { packageInfo } from './packageInfo.js';
|
||||||
|
|
||||||
// all internal exports
|
// all starred
|
||||||
export * from './address/index.js';
|
export * from './address/index.js';
|
||||||
export * from './base32/index.js';
|
export * from './base32/index.js';
|
||||||
export * from './base58/index.js';
|
export * from './base58/index.js';
|
||||||
@@ -20,8 +21,8 @@ export * from './json/index.js';
|
|||||||
export * from './keccak/index.js';
|
export * from './keccak/index.js';
|
||||||
export * from './key/index.js';
|
export * from './key/index.js';
|
||||||
export * from './mnemonic/index.js';
|
export * from './mnemonic/index.js';
|
||||||
export * from './networks.js';
|
|
||||||
export * from './nacl/index.js';
|
export * from './nacl/index.js';
|
||||||
|
export * from './networks.js';
|
||||||
export * from './pbkdf2/index.js';
|
export * from './pbkdf2/index.js';
|
||||||
export * from './random/index.js';
|
export * from './random/index.js';
|
||||||
export * from './scrypt/index.js';
|
export * from './scrypt/index.js';
|
||||||
|
|||||||
@@ -3,18 +3,8 @@
|
|||||||
|
|
||||||
import '@polkadot/x-bigint/shim';
|
import '@polkadot/x-bigint/shim';
|
||||||
|
|
||||||
import { utils as utilsNobleSecp256k1 } from '@noble/secp256k1';
|
|
||||||
|
|
||||||
import { u8aConcat } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { hmacSha256AsU8a } from './hmac/index.js';
|
|
||||||
import { cryptoWaitReady } from './crypto.js';
|
import { cryptoWaitReady } from './crypto.js';
|
||||||
|
|
||||||
// Set overrides on the secp256k1 utils
|
|
||||||
// - hmacShaSync - This needs to be set, unset by default
|
|
||||||
utilsNobleSecp256k1.hmacSha256Sync = (key: Uint8Array, ...messages: Uint8Array[]) =>
|
|
||||||
hmacSha256AsU8a(key, u8aConcat(...messages));
|
|
||||||
|
|
||||||
// start init process immediately
|
// start init process immediately
|
||||||
cryptoWaitReady().catch((): void => {
|
cryptoWaitReady().catch((): void => {
|
||||||
// shouldn't happen, logged and caught inside cryptoWaitReady
|
// shouldn't happen, logged and caught inside cryptoWaitReady
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
// no TS, this is not meant to be a global...
|
|
||||||
export {};
|
|
||||||
|
|
||||||
describe('cryptoWaitReady', (): void => {
|
describe('cryptoWaitReady', (): void => {
|
||||||
it('should return false when it cannot initialize', async (): Promise<void> => {
|
it('should return false when it cannot initialize', async (): Promise<void> => {
|
||||||
const old = global.WebAssembly;
|
const old = global.WebAssembly;
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
import type { Keypair } from '../../types.js';
|
import type { Keypair } from '../../types.js';
|
||||||
|
|
||||||
import nacl from 'tweetnacl';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name ed25519PairFromSecret
|
* @name ed25519PairFromSecret
|
||||||
* @summary Creates a new public/secret keypair from a secret.
|
* @summary Creates a new public/secret keypair from a secret.
|
||||||
@@ -19,6 +17,13 @@ import nacl from 'tweetnacl';
|
|||||||
* ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
|
* ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function ed25519PairFromSecret (secret: Uint8Array): Keypair {
|
export function ed25519PairFromSecret (secretKey: Uint8Array): Keypair {
|
||||||
return nacl.sign.keyPair.fromSecretKey(secret);
|
if (secretKey.length !== 64) {
|
||||||
|
throw new Error('Invalid secretKey provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
publicKey: secretKey.slice(32),
|
||||||
|
secretKey
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
import type { Keypair } from '../../types.js';
|
import type { Keypair } from '../../types.js';
|
||||||
|
|
||||||
import nacl from 'tweetnacl';
|
import { ed25519 } from '@noble/curves/ed25519';
|
||||||
|
|
||||||
|
import { hasBigInt, u8aConcatStrict } from '@polkadot/util';
|
||||||
import { ed25519KeypairFromSeed, isReady } from '@polkadot/wasm-crypto';
|
import { ed25519KeypairFromSeed, isReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +23,7 @@ import { ed25519KeypairFromSeed, isReady } from '@polkadot/wasm-crypto';
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function ed25519PairFromSeed (seed: Uint8Array, onlyJs?: boolean): Keypair {
|
export function ed25519PairFromSeed (seed: Uint8Array, onlyJs?: boolean): Keypair {
|
||||||
if (!onlyJs && isReady()) {
|
if (!hasBigInt || (!onlyJs && isReady())) {
|
||||||
const full = ed25519KeypairFromSeed(seed);
|
const full = ed25519KeypairFromSeed(seed);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -31,5 +32,10 @@ export function ed25519PairFromSeed (seed: Uint8Array, onlyJs?: boolean): Keypai
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return nacl.sign.keyPair.fromSeed(seed);
|
const publicKey = ed25519.getPublicKey(seed);
|
||||||
|
|
||||||
|
return {
|
||||||
|
publicKey,
|
||||||
|
secretKey: u8aConcatStrict([seed, publicKey])
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
import type { HexString } from '@polkadot/util/types';
|
import type { HexString } from '@polkadot/util/types';
|
||||||
import type { Keypair } from '../types.js';
|
import type { Keypair } from '../types.js';
|
||||||
|
|
||||||
import nacl from 'tweetnacl';
|
import { ed25519 } from '@noble/curves/ed25519';
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
import { hasBigInt, u8aToU8a } from '@polkadot/util';
|
||||||
import { ed25519Sign as wasmSign, isReady } from '@polkadot/wasm-crypto';
|
import { ed25519Sign as wasmSign, isReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,11 +26,14 @@ import { ed25519Sign as wasmSign, isReady } from '@polkadot/wasm-crypto';
|
|||||||
export function ed25519Sign (message: HexString | Uint8Array | string, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
|
export function ed25519Sign (message: HexString | Uint8Array | string, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
|
||||||
if (!secretKey) {
|
if (!secretKey) {
|
||||||
throw new Error('Expected a valid secretKey');
|
throw new Error('Expected a valid secretKey');
|
||||||
|
} else if (!publicKey) {
|
||||||
|
throw new Error('Expected a valid publicKey');
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageU8a = u8aToU8a(message);
|
const messageU8a = u8aToU8a(message);
|
||||||
|
const privateU8a = secretKey.subarray(0, 32);
|
||||||
|
|
||||||
return !onlyJs && isReady()
|
return !hasBigInt || (!onlyJs && isReady())
|
||||||
? wasmSign(publicKey as Uint8Array, secretKey.subarray(0, 32), messageU8a)
|
? wasmSign(publicKey, privateU8a, messageU8a)
|
||||||
: nacl.sign.detached(messageU8a, secretKey);
|
: ed25519.sign(messageU8a, privateU8a);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
import type { HexString } from '@polkadot/util/types';
|
import type { HexString } from '@polkadot/util/types';
|
||||||
|
|
||||||
import nacl from 'tweetnacl';
|
import { ed25519 } from '@noble/curves/ed25519';
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
import { hasBigInt, u8aToU8a } from '@polkadot/util';
|
||||||
import { ed25519Verify as wasmVerify, isReady } from '@polkadot/wasm-crypto';
|
import { ed25519Verify as wasmVerify, isReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +33,11 @@ export function ed25519Verify (message: HexString | Uint8Array | string, signatu
|
|||||||
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !onlyJs && isReady()
|
try {
|
||||||
? wasmVerify(signatureU8a, messageU8a, publicKeyU8a)
|
return !hasBigInt || (!onlyJs && isReady())
|
||||||
: nacl.sign.detached.verify(messageU8a, signatureU8a, publicKeyU8a);
|
? wasmVerify(signatureU8a, messageU8a, publicKeyU8a)
|
||||||
|
: ed25519.verify(signatureU8a, messageU8a, publicKeyU8a);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('formatAddress', () => {
|
|||||||
it('returns fails on invalid address', () => {
|
it('returns fails on invalid address', () => {
|
||||||
expect(
|
expect(
|
||||||
() => ethereumEncode('0xnotaddress')
|
() => ethereumEncode('0xnotaddress')
|
||||||
).toThrow(/Invalid address or publicKey passed/);
|
).toThrow(/Invalid address or publicKey provided/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('converts lowercase to the checksummed address', () => {
|
it('converts lowercase to the checksummed address', () => {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export function ethereumEncode (addressOrPublic?: HexString | string | Uint8Arra
|
|||||||
const u8aAddress = u8aToU8a(addressOrPublic);
|
const u8aAddress = u8aToU8a(addressOrPublic);
|
||||||
|
|
||||||
if (![20, 32, 33, 65].includes(u8aAddress.length)) {
|
if (![20, 32, 33, 65].includes(u8aAddress.length)) {
|
||||||
throw new Error('Invalid address or publicKey passed');
|
throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const address = u8aToHex(getH160(u8aAddress), -1, false);
|
const address = u8aToHex(getH160(u8aAddress), -1, false);
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ export function createAsHex <T extends (...args: never[]) => Uint8Array> (fn: T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function createBitHasher (bitLength: 256 | 512, fn: (data: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: HexString | Buffer | Uint8Array | string, onlyJs?: boolean) => Uint8Array {
|
export function createBitHasher (bitLength: 256 | 512, fn: (data: HexString | Uint8Array | string, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: HexString | Uint8Array | string, onlyJs?: boolean) => Uint8Array {
|
||||||
return (data: HexString | Buffer | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
|
return (data: HexString | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
|
||||||
fn(data, bitLength, onlyJs);
|
fn(data, bitLength, onlyJs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function createDualHasher (wa: DualHash, js: DualHash): (value: HexString | Buffer | Uint8Array | string, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array {
|
export function createDualHasher (wa: DualHash, js: DualHash): (value: HexString | Uint8Array | string, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array {
|
||||||
return (value: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs?: boolean): Uint8Array => {
|
return (value: HexString | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs?: boolean): Uint8Array => {
|
||||||
const u8a = u8aToU8a(value);
|
const u8a = u8aToU8a(value);
|
||||||
|
|
||||||
return !hasBigInt || (!onlyJs && isReady())
|
return !hasBigInt || (!onlyJs && isReady())
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
export { hmacShaAsU8a, hmacSha256AsU8a, hmacSha512AsU8a } from './shaAsU8a.js';
|
export { hmacSha256AsU8a, hmacSha512AsU8a, hmacShaAsU8a } from './shaAsU8a.js';
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ export function hmacShaAsU8a (key: Uint8Array | string, data: Uint8Array, bitLen
|
|||||||
* @name hmacSha256AsU8a
|
* @name hmacSha256AsU8a
|
||||||
* @description creates a Hmac Sha256 Uint8Array from the key & data
|
* @description creates a Hmac Sha256 Uint8Array from the key & data
|
||||||
*/
|
*/
|
||||||
export const hmacSha256AsU8a = createSha(256);
|
export const hmacSha256AsU8a = /*#__PURE__*/ createSha(256);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name hmacSha512AsU8a
|
* @name hmacSha512AsU8a
|
||||||
* @description creates a Hmac Sha512 Uint8Array from the key & data
|
* @description creates a Hmac Sha512 Uint8Array from the key & data
|
||||||
*/
|
*/
|
||||||
export const hmacSha512AsU8a = createSha(512);
|
export const hmacSha512AsU8a = /*#__PURE__*/ createSha(512);
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ export const keccak512AsU8a = /*#__PURE__*/ createBitHasher(512, keccakAsU8a);
|
|||||||
* @name keccakAsHex
|
* @name keccakAsHex
|
||||||
* @description Creates a keccak hex string from the input.
|
* @description Creates a keccak hex string from the input.
|
||||||
*/
|
*/
|
||||||
export const keccakAsHex = createAsHex(keccakAsU8a);
|
export const keccakAsHex = /*#__PURE__*/ createAsHex(keccakAsU8a);
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
* @summary Create Keccak256/512 values as hex & Uint8Array output
|
* @summary Create Keccak256/512 values as hex & Uint8Array output
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { keccakAsHex, keccakAsU8a, keccak256AsU8a, keccak512AsU8a } from './asU8a.js';
|
export { keccak256AsU8a, keccak512AsU8a, keccakAsHex, keccakAsU8a } from './asU8a.js';
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
import { ExtractResult, keyExtractPath } from './extractPath.js';
|
import type { ExtractResult } from './extractPath.js';
|
||||||
|
|
||||||
|
import { keyExtractPath } from './extractPath.js';
|
||||||
|
|
||||||
describe('keyExtractPath', (): void => {
|
describe('keyExtractPath', (): void => {
|
||||||
it('extracts properly from soft', (): void => {
|
it('extracts properly from soft', (): void => {
|
||||||
@@ -35,13 +37,13 @@ describe('keyExtractPath', (): void => {
|
|||||||
expect(test.path[1].chainCode).toEqual(Uint8Array.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
expect(test.path[1].chainCode).toEqual(Uint8Array.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not extract from invalid paths', (): void => {
|
it('does not extract from invalid paths (1)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
(): ExtractResult => keyExtractPath('1/2')
|
(): ExtractResult => keyExtractPath('1/2')
|
||||||
).toThrow(/does not match input/);
|
).toThrow(/does not match input/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not extract from invalid paths', (): void => {
|
it('does not extract from invalid paths (2)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
(): ExtractResult => keyExtractPath('hello')
|
(): ExtractResult => keyExtractPath('hello')
|
||||||
).toThrow(/does not match input/);
|
).toThrow(/does not match input/);
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
import { ExtractResult, keyExtractSuri } from './extractSuri.js';
|
import type { ExtractResult } from './extractSuri.js';
|
||||||
|
|
||||||
|
import { keyExtractSuri } from './extractSuri.js';
|
||||||
|
|
||||||
describe('keyExtractSuri', (): void => {
|
describe('keyExtractSuri', (): void => {
|
||||||
it('does not extract from invalid suri', (): void => {
|
it('does not extract from invalid suri', (): void => {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { DeriveJunction } from './DeriveJunction.js';
|
import type { DeriveJunction } from './DeriveJunction.js';
|
||||||
|
|
||||||
import { keyExtractPath } from './extractPath.js';
|
import { keyExtractPath } from './extractPath.js';
|
||||||
|
|
||||||
export interface ExtractResult {
|
export interface ExtractResult {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { Keypair, KeypairType } from '../types.js';
|
import type { Keypair, KeypairType } from '../types.js';
|
||||||
|
import type { DeriveJunction } from './DeriveJunction.js';
|
||||||
|
|
||||||
import { DeriveJunction } from './DeriveJunction.js';
|
|
||||||
import { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
import { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
||||||
import { keyHdkdEd25519 } from './hdkdEd25519.js';
|
import { keyHdkdEd25519 } from './hdkdEd25519.js';
|
||||||
import { keyHdkdSr25519 } from './hdkdSr25519.js';
|
import { keyHdkdSr25519 } from './hdkdSr25519.js';
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { Keypair } from '../types.js';
|
import type { Keypair } from '../types.js';
|
||||||
|
import type { DeriveJunction } from './DeriveJunction.js';
|
||||||
import { DeriveJunction } from './DeriveJunction.js';
|
|
||||||
|
|
||||||
export function createSeedDeriveFn (fromSeed: (seed: Uint8Array) => Keypair, derive: (seed: Uint8Array, chainCode: Uint8Array) => Uint8Array): (keypair: Keypair, junction: DeriveJunction) => Keypair {
|
export function createSeedDeriveFn (fromSeed: (seed: Uint8Array) => Keypair, derive: (seed: Uint8Array, chainCode: Uint8Array) => Uint8Array): (keypair: Keypair, junction: DeriveJunction) => Keypair {
|
||||||
return (keypair: Keypair, { chainCode, isHard }: DeriveJunction): Keypair => {
|
return (keypair: Keypair, { chainCode, isHard }: DeriveJunction): Keypair => {
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ import { secp256k1DeriveHard } from '../secp256k1/deriveHard.js';
|
|||||||
import { secp256k1PairFromSeed } from '../secp256k1/pair/fromSeed.js';
|
import { secp256k1PairFromSeed } from '../secp256k1/pair/fromSeed.js';
|
||||||
import { createSeedDeriveFn } from './hdkdDerive.js';
|
import { createSeedDeriveFn } from './hdkdDerive.js';
|
||||||
|
|
||||||
export const keyHdkdEcdsa = createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard);
|
export const keyHdkdEcdsa = /*#__PURE__*/ createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard);
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
import { ed25519DeriveHard, ed25519PairFromSeed } from '../ed25519/index.js';
|
import { ed25519DeriveHard, ed25519PairFromSeed } from '../ed25519/index.js';
|
||||||
import { createSeedDeriveFn } from './hdkdDerive.js';
|
import { createSeedDeriveFn } from './hdkdDerive.js';
|
||||||
|
|
||||||
export const keyHdkdEd25519 = createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard);
|
export const keyHdkdEd25519 = /*#__PURE__*/ createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { Keypair } from '../types.js';
|
import type { Keypair } from '../types.js';
|
||||||
|
import type { DeriveJunction } from './DeriveJunction.js';
|
||||||
|
|
||||||
import { sr25519DeriveHard } from '../sr25519/deriveHard.js';
|
import { sr25519DeriveHard } from '../sr25519/deriveHard.js';
|
||||||
import { sr25519DeriveSoft } from '../sr25519/deriveSoft.js';
|
import { sr25519DeriveSoft } from '../sr25519/deriveSoft.js';
|
||||||
import { DeriveJunction } from './DeriveJunction.js';
|
|
||||||
|
|
||||||
export function keyHdkdSr25519 (keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair {
|
export function keyHdkdSr25519 (keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair {
|
||||||
return isSoft
|
return isSoft
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
export { keyExtractPath } from './extractPath.js';
|
export { keyExtractPath } from './extractPath.js';
|
||||||
export { keyExtractSuri } from './extractSuri.js';
|
export { keyExtractSuri } from './extractSuri.js';
|
||||||
export { keyFromPath } from './fromPath.js';
|
export { keyFromPath } from './fromPath.js';
|
||||||
|
export { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
||||||
export { keyHdkdEd25519 } from './hdkdEd25519.js';
|
export { keyHdkdEd25519 } from './hdkdEd25519.js';
|
||||||
export { keyHdkdSr25519 } from './hdkdSr25519.js';
|
export { keyHdkdSr25519 } from './hdkdSr25519.js';
|
||||||
export { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
|
||||||
|
|||||||
@@ -3,25 +3,78 @@
|
|||||||
|
|
||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
import { entropyToMnemonic, mnemonicToEntropy } from './bip39.js';
|
import * as lists from './wordlists/index.js';
|
||||||
import DEFAULT_WORDLIST from './bip39-en.js';
|
import { entropyToMnemonic, generateMnemonic, mnemonicToEntropy, validateMnemonic } from './bip39.js';
|
||||||
|
|
||||||
describe('wordlist', (): void => {
|
describe('wordlists', (): void => {
|
||||||
it('has the correct number of words', (): void => {
|
for (const [lang, words] of Object.entries(lists)) {
|
||||||
expect(DEFAULT_WORDLIST).toHaveLength(2048);
|
describe(`language ${lang}`, (): void => {
|
||||||
});
|
it('has the correct number of words', (): void => {
|
||||||
|
expect(words).toHaveLength(2048);
|
||||||
|
});
|
||||||
|
|
||||||
it('has no empty words', (): void => {
|
it('has no empty words', (): void => {
|
||||||
expect(DEFAULT_WORDLIST.some((n) => !n.length || n.trim() !== n)).toEqual(false);
|
expect(
|
||||||
});
|
words.some((w) => !w.length || w.trim() !== w)
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('bip39', (): void => {
|
describe('bip39', (): void => {
|
||||||
it('has a two-way entropy <-> mnemonic', (): void => {
|
const m = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
||||||
const m = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
const e = mnemonicToEntropy(m);
|
||||||
|
|
||||||
|
it('generates a known entropy', (): void => {
|
||||||
|
expect(e).toEqual(
|
||||||
|
new Uint8Array([194, 249, 194, 50, 119, 69, 163, 120, 68, 162, 142, 34, 74, 50, 40, 197])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has a two-way entropy <-> mnemonic (default wordlist)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
entropyToMnemonic(mnemonicToEntropy(m))
|
entropyToMnemonic(mnemonicToEntropy(entropyToMnemonic(e)))
|
||||||
).toEqual(m);
|
).toEqual(m);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const [lang, words] of Object.entries(lists)) {
|
||||||
|
const isUsingList = (test: string, length = 12): void => {
|
||||||
|
const split = test.split(' ');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
split
|
||||||
|
).toHaveLength(length);
|
||||||
|
expect(
|
||||||
|
split.some((w) => words.indexOf(w) === -1)
|
||||||
|
).toEqual(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe(`language ${lang}`, (): void => {
|
||||||
|
it('has a two-way entropy <-> mnemonic', (): void => {
|
||||||
|
const test = entropyToMnemonic(e, words);
|
||||||
|
const entr = mnemonicToEntropy(test, words);
|
||||||
|
|
||||||
|
isUsingList(test);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
entr
|
||||||
|
).toEqual(e);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
entropyToMnemonic(entr, words)
|
||||||
|
).toEqual(test);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generates a valid mnemonic', (): void => {
|
||||||
|
const test = generateMnemonic(24, words);
|
||||||
|
|
||||||
|
isUsingList(test, 24);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
validateMnemonic(test, words)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,24 +19,28 @@ import { stringToU8a, u8aToU8a } from '@polkadot/util';
|
|||||||
import { pbkdf2Encode } from '../pbkdf2/index.js';
|
import { pbkdf2Encode } from '../pbkdf2/index.js';
|
||||||
import { randomAsU8a } from '../random/index.js';
|
import { randomAsU8a } from '../random/index.js';
|
||||||
import { sha256AsU8a } from '../sha/index.js';
|
import { sha256AsU8a } from '../sha/index.js';
|
||||||
import DEFAULT_WORDLIST from './bip39-en.js';
|
import DEFAULT_WORDLIST from './wordlists/en.js';
|
||||||
|
|
||||||
const INVALID_MNEMONIC = 'Invalid mnemonic';
|
const INVALID_MNEMONIC = 'Invalid mnemonic';
|
||||||
const INVALID_ENTROPY = 'Invalid entropy';
|
const INVALID_ENTROPY = 'Invalid entropy';
|
||||||
const INVALID_CHECKSUM = 'Invalid mnemonic checksum';
|
const INVALID_CHECKSUM = 'Invalid mnemonic checksum';
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
function normalize (str?: string): string {
|
function normalize (str?: string): string {
|
||||||
return (str || '').normalize('NFKD');
|
return (str || '').normalize('NFKD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
function binaryToByte (bin: string): number {
|
function binaryToByte (bin: string): number {
|
||||||
return parseInt(bin, 2);
|
return parseInt(bin, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
function bytesToBinary (bytes: number[]): string {
|
function bytesToBinary (bytes: number[]): string {
|
||||||
return bytes.map((x) => x.toString(2).padStart(8, '0')).join('');
|
return bytes.map((x) => x.toString(2).padStart(8, '0')).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
function deriveChecksumBits (entropyBuffer: Uint8Array): string {
|
function deriveChecksumBits (entropyBuffer: Uint8Array): string {
|
||||||
return bytesToBinary(
|
return bytesToBinary(
|
||||||
Array.from(sha256AsU8a(entropyBuffer))
|
Array.from(sha256AsU8a(entropyBuffer))
|
||||||
@@ -50,7 +54,7 @@ export function mnemonicToSeedSync (mnemonic: string, password?: string): Uint8A
|
|||||||
).password;
|
).password;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
export function mnemonicToEntropy (mnemonic: string, wordlist: string[] = DEFAULT_WORDLIST): Uint8Array {
|
||||||
const words = normalize(mnemonic).split(' ');
|
const words = normalize(mnemonic).split(' ');
|
||||||
|
|
||||||
if (words.length % 3 !== 0) {
|
if (words.length % 3 !== 0) {
|
||||||
@@ -60,7 +64,7 @@ export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
|||||||
// convert word indices to 11 bit binary strings
|
// convert word indices to 11 bit binary strings
|
||||||
const bits = words
|
const bits = words
|
||||||
.map((word): string => {
|
.map((word): string => {
|
||||||
const index = DEFAULT_WORDLIST.indexOf(word);
|
const index = wordlist.indexOf(word);
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
throw new Error(INVALID_MNEMONIC);
|
throw new Error(INVALID_MNEMONIC);
|
||||||
@@ -92,14 +96,14 @@ export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
|||||||
return entropy;
|
return entropy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function entropyToMnemonic (entropy: Uint8Array): string {
|
export function entropyToMnemonic (entropy: Uint8Array, wordlist: string[] = DEFAULT_WORDLIST): string {
|
||||||
// 128 <= ENT <= 256
|
// 128 <= ENT <= 256
|
||||||
if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) {
|
if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) {
|
||||||
throw new Error(INVALID_ENTROPY);
|
throw new Error(INVALID_ENTROPY);
|
||||||
}
|
}
|
||||||
|
|
||||||
const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g);
|
const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g);
|
||||||
const mapped = matched && matched.map((binary) => DEFAULT_WORDLIST[binaryToByte(binary)]);
|
const mapped = matched && matched.map((b) => wordlist[binaryToByte(b)]);
|
||||||
|
|
||||||
if (!mapped || (mapped.length < 12)) {
|
if (!mapped || (mapped.length < 12)) {
|
||||||
throw new Error('Unable to map entropy to mnemonic');
|
throw new Error('Unable to map entropy to mnemonic');
|
||||||
@@ -108,13 +112,13 @@ export function entropyToMnemonic (entropy: Uint8Array): string {
|
|||||||
return mapped.join(' ');
|
return mapped.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateMnemonic (numWords: 12 | 15 | 18 | 21 | 24): string {
|
export function generateMnemonic (numWords: 12 | 15 | 18 | 21 | 24, wordlist?: string[]): string {
|
||||||
return entropyToMnemonic(randomAsU8a((numWords / 3) * 4));
|
return entropyToMnemonic(randomAsU8a((numWords / 3) * 4), wordlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateMnemonic (mnemonic: string): boolean {
|
export function validateMnemonic (mnemonic: string, wordlist?: string[]): boolean {
|
||||||
try {
|
try {
|
||||||
mnemonicToEntropy(mnemonic);
|
mnemonicToEntropy(mnemonic, wordlist);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
import { cryptoWaitReady } from '../index.js';
|
import { cryptoWaitReady } from '../index.js';
|
||||||
|
import { french as frenchWords } from './wordlists/index.js';
|
||||||
import { mnemonicGenerate } from './generate.js';
|
import { mnemonicGenerate } from './generate.js';
|
||||||
import { mnemonicValidate } from './validate.js';
|
import { mnemonicValidate } from './validate.js';
|
||||||
|
|
||||||
@@ -16,11 +17,27 @@ describe('mnemonicGenerate', (): void => {
|
|||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('generates a french mnemonic', (): void => {
|
||||||
|
const mnemonic = mnemonicGenerate(24, frenchWords);
|
||||||
|
const words = mnemonic.split(' ');
|
||||||
|
|
||||||
|
expect(words).toHaveLength(24);
|
||||||
|
expect(
|
||||||
|
mnemonicValidate(mnemonic, frenchWords)
|
||||||
|
).toEqual(true);
|
||||||
|
expect(
|
||||||
|
mnemonicValidate(mnemonic)
|
||||||
|
).toEqual(false);
|
||||||
|
expect(
|
||||||
|
words.every((w) => frenchWords.includes(w))
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
for (const onlyJs of [false, true]) {
|
for (const onlyJs of [false, true]) {
|
||||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||||
for (const num of [12, 15, 18, 21, 24] as const) {
|
for (const num of [12, 15, 18, 21, 24] as const) {
|
||||||
it(`generates a valid mnemonic (${num} words)`, (): void => {
|
it(`generates a valid mnemonic (${num} words)`, (): void => {
|
||||||
const mnemonic = mnemonicGenerate(num, onlyJs);
|
const mnemonic = mnemonicGenerate(num, undefined, onlyJs);
|
||||||
const isValid = mnemonicValidate(mnemonic);
|
const isValid = mnemonicValidate(mnemonic);
|
||||||
|
|
||||||
expect(mnemonic.split(' ')).toHaveLength(num);
|
expect(mnemonic.split(' ')).toHaveLength(num);
|
||||||
@@ -29,8 +46,8 @@ describe('mnemonicGenerate', (): void => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it('generates non-deterministic', (): void => {
|
it('generates non-deterministic', (): void => {
|
||||||
const m1 = mnemonicGenerate(24, onlyJs);
|
const m1 = mnemonicGenerate(24, undefined, onlyJs);
|
||||||
const m2 = mnemonicGenerate(24, onlyJs);
|
const m2 = mnemonicGenerate(24, undefined, onlyJs);
|
||||||
|
|
||||||
expect(m1 === m2).toEqual(false);
|
expect(m1 === m2).toEqual(false);
|
||||||
expect(mnemonicValidate(m1)).toEqual(true);
|
expect(mnemonicValidate(m1)).toEqual(true);
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import { generateMnemonic } from './bip39.js';
|
|||||||
* const mnemonic = mnemonicGenerate(); // => string
|
* const mnemonic = mnemonicGenerate(); // => string
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function mnemonicGenerate (numWords: 12 | 15 | 18 | 21 | 24 = 12, onlyJs?: boolean): string {
|
export function mnemonicGenerate (numWords: 12 | 15 | 18 | 21 | 24 = 12, wordlist?: string[], onlyJs?: boolean): string {
|
||||||
return !hasBigInt || (!onlyJs && isReady())
|
return !hasBigInt || (!wordlist && !onlyJs && isReady())
|
||||||
? bip39Generate(numWords)
|
? bip39Generate(numWords)
|
||||||
: generateMnemonic(numWords);
|
: generateMnemonic(numWords, wordlist);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { u8aToHex } from '@polkadot/util';
|
|||||||
|
|
||||||
import { cryptoWaitReady } from '../index.js';
|
import { cryptoWaitReady } from '../index.js';
|
||||||
import tests from '../sr25519/pair/testing.spec.js';
|
import tests from '../sr25519/pair/testing.spec.js';
|
||||||
|
import { french as frenchWords } from './wordlists/index.js';
|
||||||
import { mnemonicToEntropy } from './toEntropy.js';
|
import { mnemonicToEntropy } from './toEntropy.js';
|
||||||
|
|
||||||
await cryptoWaitReady();
|
await cryptoWaitReady();
|
||||||
@@ -16,9 +17,20 @@ describe('mnemonicToEntropy', (): void => {
|
|||||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||||
tests.forEach(([mnemonic, entropy], index): void => {
|
tests.forEach(([mnemonic, entropy], index): void => {
|
||||||
it(`Created correct entropy for ${index}`, (): void => {
|
it(`Created correct entropy for ${index}`, (): void => {
|
||||||
expect(u8aToHex(mnemonicToEntropy(mnemonic, onlyJs))).toEqual(entropy);
|
expect(u8aToHex(mnemonicToEntropy(mnemonic, undefined, onlyJs))).toEqual(entropy);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('has the correct entropy for non-Englist mnemonics', (): void => {
|
||||||
|
const mnemonic = 'pompier circuler pulpe injure aspect abyssal nuque boueux équerre balisage pieuvre médecin petit suffixe soleil cumuler monstre arlequin liasse pixel garrigue noble buisson scandale';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => mnemonicToEntropy(mnemonic)
|
||||||
|
).toThrow();
|
||||||
|
expect(
|
||||||
|
mnemonicToEntropy(mnemonic, frenchWords)
|
||||||
|
).toEqual(new Uint8Array([189, 230, 55, 17, 65, 33, 40, 4, 106, 9, 11, 88, 227, 26, 229, 76, 59, 123, 200, 55, 177, 232, 158, 66, 34, 54, 93, 54, 255, 74, 137, 70]));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { bip39ToEntropy, isReady } from '@polkadot/wasm-crypto';
|
|||||||
|
|
||||||
import { mnemonicToEntropy as jsToEntropy } from './bip39.js';
|
import { mnemonicToEntropy as jsToEntropy } from './bip39.js';
|
||||||
|
|
||||||
export function mnemonicToEntropy (mnemonic: string, onlyJs?: boolean): Uint8Array {
|
export function mnemonicToEntropy (mnemonic: string, wordlist?: string[], onlyJs?: boolean): Uint8Array {
|
||||||
return !hasBigInt || (!onlyJs && isReady())
|
return !hasBigInt || (!wordlist && !onlyJs && isReady())
|
||||||
? bip39ToEntropy(mnemonic)
|
? bip39ToEntropy(mnemonic)
|
||||||
: jsToEntropy(mnemonic);
|
: jsToEntropy(mnemonic, wordlist);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { u8aEq, u8aToHex } from '@polkadot/util';
|
|||||||
|
|
||||||
import { cryptoWaitReady } from '../index.js';
|
import { cryptoWaitReady } from '../index.js';
|
||||||
import tests from '../sr25519/pair/testing.spec.js';
|
import tests from '../sr25519/pair/testing.spec.js';
|
||||||
|
import { korean as koreanWords } from './wordlists/index.js';
|
||||||
import { mnemonicToMiniSecret } from './toMiniSecret.js';
|
import { mnemonicToMiniSecret } from './toMiniSecret.js';
|
||||||
|
|
||||||
const MNEMONIC = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
const MNEMONIC = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
||||||
@@ -19,31 +20,42 @@ describe('mnemonicToMiniSecret', (): void => {
|
|||||||
it(`generates Wasm & Js equivalents for password=${password || 'undefined'}`, (): void => {
|
it(`generates Wasm & Js equivalents for password=${password || 'undefined'}`, (): void => {
|
||||||
expect(
|
expect(
|
||||||
u8aEq(
|
u8aEq(
|
||||||
mnemonicToMiniSecret(MNEMONIC, password, true),
|
mnemonicToMiniSecret(MNEMONIC, password, undefined, true),
|
||||||
mnemonicToMiniSecret(MNEMONIC, password, false)
|
mnemonicToMiniSecret(MNEMONIC, password, undefined, false)
|
||||||
)
|
)
|
||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('creates a known minisecret from a non-english mnemonic', (): void => {
|
||||||
|
const mnemonic = '엉덩이 능동적 숫자 팩시밀리 비난 서적 파출소 도움 독창적 인생 상류 먼지 답변 음반 수박 사업 노란색 공사 우체국 특급 도대체 금지 굉장히 고무신';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
() => mnemonicToMiniSecret(mnemonic, 'testing')
|
||||||
|
).toThrow();
|
||||||
|
expect(
|
||||||
|
u8aToHex(mnemonicToMiniSecret(mnemonic, 'testing', koreanWords))
|
||||||
|
).toEqual('0xefa278a62535581767a2f49cb542ed91b65fb911e1b05e7a09c702b257f10c13');
|
||||||
|
});
|
||||||
|
|
||||||
for (const onlyJs of [false, true]) {
|
for (const onlyJs of [false, true]) {
|
||||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||||
it('generates a valid seed', (): void => {
|
it('generates a valid seed', (): void => {
|
||||||
expect(
|
expect(
|
||||||
u8aToHex(mnemonicToMiniSecret(MNEMONIC, undefined, onlyJs))
|
u8aToHex(mnemonicToMiniSecret(MNEMONIC, undefined, undefined, onlyJs))
|
||||||
).toEqual(SEED);
|
).toEqual(SEED);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fails with non-mnemonics', (): void => {
|
it('fails with non-mnemonics', (): void => {
|
||||||
expect(
|
expect(
|
||||||
() => mnemonicToMiniSecret('foo bar baz', undefined, onlyJs)
|
() => mnemonicToMiniSecret('foo bar baz', undefined, undefined, onlyJs)
|
||||||
).toThrow(/mnemonic specified/);
|
).toThrow(/mnemonic specified/);
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.forEach(([mnemonic, , seed], index): void => {
|
tests.forEach(([mnemonic, , seed], index): void => {
|
||||||
it(`Created correct seed for ${index}`, (): void => {
|
it(`Created correct seed for ${index}`, (): void => {
|
||||||
expect(
|
expect(
|
||||||
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate', onlyJs))
|
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate', undefined, onlyJs))
|
||||||
).toEqual(
|
).toEqual(
|
||||||
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
|
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
|
||||||
seed.substring(0, 66)
|
seed.substring(0, 66)
|
||||||
|
|||||||
@@ -8,16 +8,14 @@ import { pbkdf2Encode } from '../pbkdf2/index.js';
|
|||||||
import { mnemonicToEntropy } from './toEntropy.js';
|
import { mnemonicToEntropy } from './toEntropy.js';
|
||||||
import { mnemonicValidate } from './validate.js';
|
import { mnemonicValidate } from './validate.js';
|
||||||
|
|
||||||
export function mnemonicToMiniSecret (mnemonic: string, password = '', onlyJs?: boolean): Uint8Array {
|
export function mnemonicToMiniSecret (mnemonic: string, password = '', wordlist?: string[], onlyJs?: boolean): Uint8Array {
|
||||||
if (!mnemonicValidate(mnemonic)) {
|
if (!mnemonicValidate(mnemonic, wordlist, onlyJs)) {
|
||||||
throw new Error('Invalid bip39 mnemonic specified');
|
throw new Error('Invalid bip39 mnemonic specified');
|
||||||
}
|
} else if (!wordlist && !onlyJs && isReady()) {
|
||||||
|
|
||||||
if (!onlyJs && isReady()) {
|
|
||||||
return bip39ToMiniSecret(mnemonic, password);
|
return bip39ToMiniSecret(mnemonic, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
const entropy = mnemonicToEntropy(mnemonic);
|
const entropy = mnemonicToEntropy(mnemonic, wordlist);
|
||||||
const salt = stringToU8a(`mnemonic${password}`);
|
const salt = stringToU8a(`mnemonic${password}`);
|
||||||
|
|
||||||
// return the first 32 bytes as the seed
|
// return the first 32 bytes as the seed
|
||||||
|
|||||||
@@ -28,14 +28,14 @@ for (const onlyJsMnemonic of [false, true]) {
|
|||||||
// NOTE we cannot actually use the onlyJsMnemonic flag here
|
// NOTE we cannot actually use the onlyJsMnemonic flag here
|
||||||
const mnemonic = mnemonicGenerate(12);
|
const mnemonic = mnemonicGenerate(12);
|
||||||
|
|
||||||
describe(mnemonic, (): void => {
|
describe(`${mnemonic}`, (): void => {
|
||||||
// do iterations to check and re-check that all matches
|
// do iterations to check and re-check that all matches
|
||||||
for (const count of arrayRange(NUM_CHECKS)) {
|
for (const count of arrayRange(NUM_CHECKS)) {
|
||||||
it(`check=${count + 1}`, (): void => {
|
it(`check=${count + 1}`, (): void => {
|
||||||
const minisecret = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', onlyJsMnemonic);
|
const minisecret = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', undefined, onlyJsMnemonic);
|
||||||
const edpub = ed25519PairFromSeed(minisecret).publicKey;
|
const edpub = ed25519PairFromSeed(minisecret).publicKey;
|
||||||
const srpub = sr25519PairFromSeed(minisecret).publicKey;
|
const srpub = sr25519PairFromSeed(minisecret).publicKey;
|
||||||
const testmini = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', onlyJsMini);
|
const testmini = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', undefined, onlyJsMini);
|
||||||
|
|
||||||
// explicit minisecret compare
|
// explicit minisecret compare
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||||
|
|
||||||
import { cryptoWaitReady } from '../index.js';
|
import { cryptoWaitReady } from '../index.js';
|
||||||
|
import { french as frenchWords } from './wordlists/index.js';
|
||||||
import { mnemonicValidate } from './validate.js';
|
import { mnemonicValidate } from './validate.js';
|
||||||
|
|
||||||
await cryptoWaitReady();
|
await cryptoWaitReady();
|
||||||
@@ -13,15 +14,26 @@ describe('mnemonicValidate', (): void => {
|
|||||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||||
it('returns true on valid', (): void => {
|
it('returns true on valid', (): void => {
|
||||||
expect(
|
expect(
|
||||||
mnemonicValidate('seed sock milk update focus rotate barely fade car face mechanic mercy', onlyJs)
|
mnemonicValidate('seed sock milk update focus rotate barely fade car face mechanic mercy', undefined, onlyJs)
|
||||||
).toEqual(true);
|
).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns false on invalid', (): void => {
|
it('returns false on invalid', (): void => {
|
||||||
expect(
|
expect(
|
||||||
mnemonicValidate('wine photo extra cushion basket dwarf humor cloud truck job boat submit', onlyJs)
|
mnemonicValidate('wine photo extra cushion basket dwarf humor cloud truck job boat submit', undefined, onlyJs)
|
||||||
).toEqual(false);
|
).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('allows usage of a different wordlist', (): void => {
|
||||||
|
const mnemonic = 'pompier circuler pulpe injure aspect abyssal nuque boueux équerre balisage pieuvre médecin petit suffixe soleil cumuler monstre arlequin liasse pixel garrigue noble buisson scandale';
|
||||||
|
|
||||||
|
expect(
|
||||||
|
mnemonicValidate(mnemonic, frenchWords)
|
||||||
|
).toEqual(true);
|
||||||
|
expect(
|
||||||
|
mnemonicValidate(mnemonic)
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import { validateMnemonic } from './bip39.js';
|
|||||||
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
|
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function mnemonicValidate (mnemonic: string, onlyJs?: boolean): boolean {
|
export function mnemonicValidate (mnemonic: string, wordlist?: string[], onlyJs?: boolean): boolean {
|
||||||
return !hasBigInt || (!onlyJs && isReady())
|
return !hasBigInt || (!wordlist && !onlyJs && isReady())
|
||||||
? bip39Validate(mnemonic)
|
? bip39Validate(mnemonic)
|
||||||
: validateMnemonic(mnemonic);
|
: validateMnemonic(mnemonic, wordlist);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
export { default as english } from './en.js';
|
||||||
|
export { default as spanish } from './es.js';
|
||||||
|
export { default as french } from './fr.js';
|
||||||
|
export { default as italian } from './it.js';
|
||||||
|
export { default as japanese } from './jp.js';
|
||||||
|
export { default as korean } from './ko.js';
|
||||||
|
export { default as chineseSimplified } from './zh-s.js';
|
||||||
|
export { default as chineseTraditional } from './zh-t.js';
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user