Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f55e88c116 | ||
|
|
abd4cfdd1f | ||
|
|
f261ea2924 | ||
|
|
f14d2681b1 | ||
|
|
b9be030f12 | ||
|
|
bc103d9479 | ||
|
|
c76c754741 | ||
|
|
bd21e730b3 | ||
|
|
a2cfdb8ca7 | ||
|
|
4857de9f38 | ||
|
|
d525b8c92d | ||
|
|
2afbce2652 | ||
|
|
3c7525649e | ||
|
|
6ebcc2dd6d | ||
|
|
120438d7e6 | ||
|
|
f5f1bc6f4f | ||
|
|
28d5302fd6 | ||
|
|
773cc29b11 | ||
|
|
a20c7eb2e5 | ||
|
|
487d0d9a57 | ||
|
|
a910e9ce6f | ||
|
|
1062de7aa8 | ||
|
|
4cabc67b24 | ||
|
|
13bc84e30b | ||
|
|
67fe7738d8 | ||
|
|
13c6b4e553 | ||
|
|
9306f9db92 | ||
|
|
62a30f258e | ||
|
|
81609aba59 | ||
|
|
301d73d13f | ||
|
|
92abf4463d | ||
|
|
b018f78b77 | ||
|
|
608117f04a | ||
|
|
2ac00565b0 | ||
|
|
673a59af58 | ||
|
|
aa394fe7cd | ||
|
|
ee7f2cc7f5 | ||
|
|
da6efc821e | ||
|
|
a3b884d437 | ||
|
|
560c054750 | ||
|
|
09621d0010 | ||
|
|
37a81d9594 | ||
|
|
62182bae03 | ||
|
|
2ee03a5f81 | ||
|
|
7a5a88a135 | ||
|
|
f4e0e2111f | ||
|
|
aac902011e | ||
|
|
a030330808 | ||
|
|
d108beafd4 | ||
|
|
90e20ed4d2 | ||
|
|
723ec10fa1 | ||
|
|
cf9082e03a | ||
|
|
3dce4fe04a | ||
|
|
55ebc4f0d9 | ||
|
|
ce2122e9fa | ||
|
|
0fb55fe633 | ||
|
|
adca13bc8c | ||
|
|
b939c3593c | ||
|
|
aa70b81a89 | ||
|
|
f3e1d6beda | ||
|
|
754bc4dc21 | ||
|
|
a8df82dfe0 | ||
|
|
4ff56f5cfe | ||
|
|
1fd9f04458 | ||
|
|
a28306f487 | ||
|
|
19941bcb61 | ||
|
|
2cb85866ab | ||
|
|
8556de1fa2 | ||
|
|
143d070d21 | ||
|
|
2a53b1121e | ||
|
|
0733137f79 | ||
|
|
cc918660cb | ||
|
|
3527f8c7d9 | ||
|
|
41caf2fd6d | ||
|
|
d407513dd1 | ||
|
|
bd76349552 | ||
|
|
0ec894b732 | ||
|
|
be4cb52dd3 | ||
|
|
456eaeeb94 | ||
|
|
0ec50b6159 | ||
|
|
98336fd2e5 | ||
|
|
7b3bbd3ef2 | ||
|
|
49afd1fe09 | ||
|
|
0df17104d5 | ||
|
|
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 |
@@ -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
|
||||
with:
|
||||
github-token: ${{ secrets.GH_PAT_BOT }}
|
||||
issue-lock-inactive-days: '7'
|
||||
issue-lock-comment: >
|
||||
issue-inactive-days: '7'
|
||||
issue-comment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue
|
||||
if you think you have a related problem or query.
|
||||
pr-lock-inactive-days: '2'
|
||||
pr-lock-comment: >
|
||||
pr-inactive-days: '2'
|
||||
pr-comment: >
|
||||
This pull request has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
||||
|
||||
@@ -22,5 +22,5 @@ jobs:
|
||||
- name: ${{ matrix.step }}
|
||||
if: always()
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn install --immutable
|
||||
yarn ${{ matrix.step }}
|
||||
|
||||
@@ -27,5 +27,5 @@ jobs:
|
||||
node-version: 'lts/*'
|
||||
- name: ${{ matrix.step }}
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn install --immutable
|
||||
yarn ${{ matrix.step }}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/dev authors & contributors
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = require('@polkadot/dev/config/prettier.cjs');
|
||||
|
||||
@@ -2,6 +2,11 @@ enableImmutableInstalls: false
|
||||
|
||||
enableProgressBars: false
|
||||
|
||||
logFilters:
|
||||
# Discard any "cannot be found in cache" messages
|
||||
- code: YN0013
|
||||
level: discard
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
|
||||
+121
@@ -1,5 +1,126 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 12.6.1 Nov 18, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Ledger support for Quartz (Thanks to https://github.com/CertainLach)
|
||||
- Add flag to disable same-version esm/cjs warnings (Thanks to https://github.com/forgetso)
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust logger check for `process.env`
|
||||
- Adjust `isRiscV` helper to check for `PVM\0` bytes
|
||||
- Drop support for Node 16 (EOL 11 Sep 2023)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.5.1 Sep 15, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add `isRiskV` helper (Thanks to https://github.com/peetzweg)
|
||||
- Ledger support for Enjin & Matrixchain (Thanks to https://github.com/leonardocustodio)
|
||||
|
||||
Changes:
|
||||
|
||||
- Expand interface type comments (assists in-editor helpers)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.4.2 Aug 23, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix `u8aTo{BigInt, Bn, Number}` for non-negative `i{8, 16, 32...}` inputs
|
||||
- Extend `u8aToBuffer` with `hasBuffer` check
|
||||
- Adjust util tests (extract input/output arrays)
|
||||
|
||||
|
||||
## 12.4.1 Aug 17, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Add support for Ledger `signRaw`, as exposed by lower-level
|
||||
- Update code to use `?.` shortcuts where appropriate
|
||||
- Adjust `u8aToBuffer` & `isBuffer` typings to not require `Buffer`
|
||||
- Use `stringify/import.meta.url` helpers in specs
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 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:
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
1577 Jaco 11.1.3 (#1789)
|
||||
12 Carlo Sala feat(networks): support ledger for pendulum (#1739)
|
||||
1665 Jaco 12.6.1 (#1897)
|
||||
13 Carlo Sala feat(networks): add zeitgeist Ledger support (#1840)
|
||||
9 Antoine Estienne Add eth uri keyring test (#1291)
|
||||
6 Amaury Martiny Add tests from Rust (#283)
|
||||
5 Jakub Pánik Add HydraDX parachain to genesis (#1583)
|
||||
@@ -25,6 +25,7 @@
|
||||
1 Brad Larson [FIX] Adjust error message (#646)
|
||||
1 Cameron Fairchild Add bittensor details (#1783)
|
||||
1 Carlos Medeiros add hydradx to knownLedger (#1647)
|
||||
1 Chris Get rid of warnings for dual esm and cjs packages of the same version (#1890)
|
||||
1 Eliott Teissonniere add nodle ledger specs (#1089)
|
||||
1 Guilane DENGUIR feat(VTB): Added support for VTB blockchain (#1651)
|
||||
1 h4x3rotab Throws an error when signing with a locked keypair (#578)
|
||||
@@ -36,6 +37,7 @@
|
||||
1 JesseAbram added check if valid address to docs (#440)
|
||||
1 joe petrowski Add example for multisig address creation (#590)
|
||||
1 kaelnew add ledger support for stafi (#1569)
|
||||
1 Leonardo Custodio Ledger support (#1879)
|
||||
1 Lezek123 logger - wildcard include/exclude with DEBUG env (#932)
|
||||
1 Mario Neises remove redudant export (#257)
|
||||
1 Miguel Hervas Add CFG Ledger Support (#1057)
|
||||
@@ -43,11 +45,13 @@
|
||||
1 Mohsan Riaz Add Ternoa for ledger hardware support (#1711)
|
||||
1 nahuseyoum Reserving 65 for Aventus based on the new extended range (#871)
|
||||
1 Nantian add acala ledger config (#1485)
|
||||
1 peetzweg/ adds `isRiscV` guard function similar to isWasm (#1878)
|
||||
1 qwer951123 Add acala genesis (#1161)
|
||||
1 Raoul Millais Fix yarn add instructions in x-global README (#873)
|
||||
1 Raymond Zhong Add Edgeware ledger app (#1006)
|
||||
1 Reto Trinkler Adding 4 as address type of ss58 for Katal Chain (#639)
|
||||
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 Thibaut Sardan add hasLedgerSupport prop to networks (#835)
|
||||
1 Tomokazu Kozuma fix comment (#1119)
|
||||
@@ -55,4 +59,5 @@
|
||||
1 Wei Tang ss58: add Kulupu prefix to the list (#595)
|
||||
1 WoeOm Handing high precision scenes (#450)
|
||||
1 xx network Add xxnetwork genesis hash and ledger app (#1463)
|
||||
1 Yaroslav Bolyukin Add quartz support for ledger, update unique slip-0044 identifier (#1882)
|
||||
1 Yuri Extra check for process for browser bundles (#923)
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import baseConfig from '@polkadot/dev/config/eslint';
|
||||
|
||||
export default [
|
||||
...baseConfig
|
||||
];
|
||||
+6
-6
@@ -14,10 +14,10 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"versions": {
|
||||
"git": "11.1.3",
|
||||
"npm": "11.1.3"
|
||||
"git": "12.6.1",
|
||||
"npm": "12.6.1"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@@ -37,10 +37,10 @@
|
||||
"test:one": "polkadot-dev-run-test --env browser"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.72.29",
|
||||
"@types/node": "^18.15.11"
|
||||
"@polkadot/dev": "^0.77.1",
|
||||
"@types/node": "^20.9.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"typescript": "^5.0.3"
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger-transports#readme",
|
||||
"license": "Apache-2.0",
|
||||
@@ -14,18 +14,18 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"browser": "browser.js",
|
||||
"main": "node.js",
|
||||
"react-native": "react-native.js",
|
||||
"dependencies": {
|
||||
"@ledgerhq/hw-transport": "^6.28.1",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.27.12",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.12",
|
||||
"@polkadot/util": "11.1.3",
|
||||
"tslib": "^2.5.0"
|
||||
"@ledgerhq/hw-transport": "^6.29.0",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.27.20",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.20",
|
||||
"@polkadot/util": "12.6.1",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.9"
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.29.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '11.1.3' };
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '12.6.1' };
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// CJS, so we use import * syntax
|
||||
import type * as HwTransport from '@ledgerhq/hw-transport';
|
||||
|
||||
// u2f is deprecated an therefore not added
|
||||
export type TransportType = 'hid' | 'webusb';
|
||||
|
||||
// The actual namespaced Transport interface, imported via
|
||||
//
|
||||
// import type Transport from '@ledgerhq/hw-transport';
|
||||
//
|
||||
// does not work on moduleResolution: nodenext, so we just go with a
|
||||
// very light interface for Transport (and then TransportStatic).
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface Transport {
|
||||
// empty on purpose, just a stub
|
||||
}
|
||||
export type Transport = HwTransport.default;
|
||||
|
||||
export interface TransportDef {
|
||||
/** Create a transport to be used in Ledger operations */
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../util/tsconfig.build.json" }
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger#readme",
|
||||
"license": "Apache-2.0",
|
||||
@@ -17,12 +17,12 @@
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@polkadot/hw-ledger-transports": "11.1.3",
|
||||
"@polkadot/util": "11.1.3",
|
||||
"@zondax/ledger-substrate": "^0.40.6",
|
||||
"tslib": "^2.5.0"
|
||||
"@polkadot/hw-ledger-transports": "12.6.1",
|
||||
"@polkadot/util": "12.6.1",
|
||||
"@zondax/ledger-substrate": "^0.41.3",
|
||||
"tslib": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } fr
|
||||
import { newSubstrateApp } from '@zondax/ledger-substrate';
|
||||
|
||||
import { transports } from '@polkadot/hw-ledger-transports';
|
||||
import { hexAddPrefix, u8aToBuffer } from '@polkadot/util';
|
||||
import { hexAddPrefix, u8aToBuffer, u8aWrapBytes } from '@polkadot/util';
|
||||
|
||||
import { LEDGER_DEFAULT_ACCOUNT, LEDGER_DEFAULT_CHANGE, LEDGER_DEFAULT_INDEX, LEDGER_SUCCESS_CODE } from './constants.js';
|
||||
import { ledgerApps } from './defaults.js';
|
||||
@@ -30,16 +30,31 @@ async function wrapError <T extends WrappedResult> (promise: Promise<T>): Promis
|
||||
return result;
|
||||
}
|
||||
|
||||
// A very basic wrapper for a ledger app -
|
||||
// - it connects automatically, creating an app as required
|
||||
// - Promises return errors (instead of wrapper errors)
|
||||
/** @internal Wraps a sign/signRaw call and returns the associated signature */
|
||||
function sign (method: 'sign' | 'signRaw', message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): (app: SubstrateApp) => Promise<LedgerSignature> {
|
||||
return async (app: SubstrateApp): Promise<LedgerSignature> => {
|
||||
const { signature } = await wrapError(app[method](account + accountOffset, change, addressIndex + addressOffset, u8aToBuffer(message)));
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Ledger
|
||||
*
|
||||
* @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 {
|
||||
readonly #ledgerName: string;
|
||||
readonly #transportDef: TransportDef;
|
||||
|
||||
#app: SubstrateApp | null = null;
|
||||
|
||||
#ledgerName: string;
|
||||
|
||||
#transportDef: TransportDef;
|
||||
|
||||
constructor (transport: TransportType, chain: Chain) {
|
||||
const ledgerName = ledgerApps[chain];
|
||||
const transportDef = transports.find(({ type }) => type === transport);
|
||||
@@ -85,17 +100,17 @@ export class Ledger {
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a transcation on the Ledger device
|
||||
* 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> {
|
||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
|
||||
const buffer = u8aToBuffer(message);
|
||||
const { signature } = await wrapError(app.sign(account + accountOffset, change, addressIndex + addressOffset, buffer));
|
||||
public async sign (message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial<AccountOptions>): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('sign', message, accountOffset, addressOffset, options));
|
||||
}
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Signs a message (non-transactional) on the Ledger device
|
||||
*/
|
||||
public async signRaw (message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial<AccountOptions>): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('signRaw', u8aWrapBytes(message), accountOffset, addressOffset, options));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@ export const ledgerApps: Record<string, string> = {
|
||||
darwinia: 'Darwinia',
|
||||
'dock-mainnet': 'Dock',
|
||||
edgeware: 'Edgeware',
|
||||
enjin: 'Enjin',
|
||||
equilibrium: 'Equilibrium',
|
||||
genshiro: 'Genshiro',
|
||||
hydradx: 'HydraDX',
|
||||
@@ -22,6 +23,7 @@ export const ledgerApps: Record<string, string> = {
|
||||
karura: 'Karura',
|
||||
khala: 'Khala',
|
||||
kusama: 'Kusama',
|
||||
matrixchain: 'Matrixchain',
|
||||
nodle: 'Nodle',
|
||||
origintrail: 'OriginTrail',
|
||||
parallel: 'Parallel',
|
||||
@@ -31,6 +33,7 @@ export const ledgerApps: Record<string, string> = {
|
||||
polkadex: 'Polkadex',
|
||||
polkadot: 'Polkadot',
|
||||
polymesh: 'Polymesh',
|
||||
quartz: 'Quartz',
|
||||
sora: 'Sora',
|
||||
stafi: 'Stafi',
|
||||
statemine: 'Statemine',
|
||||
@@ -38,5 +41,6 @@ export const ledgerApps: Record<string, string> = {
|
||||
ternoa: 'Ternoa',
|
||||
unique: 'Unique',
|
||||
vtb: 'VTB',
|
||||
xxnetwork: 'XXNetwork'
|
||||
xxnetwork: 'XXNetwork',
|
||||
zeitgeist: 'Zeitgeist'
|
||||
};
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '11.1.3' };
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '12.6.1' };
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../hw-ledger-transports/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",
|
||||
"description": "Keyring management",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||
"license": "Apache-2.0",
|
||||
@@ -18,15 +18,15 @@
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@polkadot/util": "11.1.3",
|
||||
"@polkadot/util-crypto": "11.1.3",
|
||||
"tslib": "^2.5.0"
|
||||
"@polkadot/util": "12.6.1",
|
||||
"@polkadot/util-crypto": "12.6.1",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@polkadot/util": "11.1.3",
|
||||
"@polkadot/util-crypto": "11.1.3"
|
||||
"@polkadot/util": "12.6.1",
|
||||
"@polkadot/util-crypto": "12.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Keyring } from './keyring.js';
|
||||
|
||||
// all external
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
export { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
export * from './defaults.js';
|
||||
|
||||
export { createPair } from './pair/index.js';
|
||||
// all named
|
||||
export { Keyring } from './keyring.js';
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
export { createPair } from './pair/index.js';
|
||||
export { createTestKeyring } from './testing.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;
|
||||
|
||||
#ss58?: number;
|
||||
#ss58?: number | undefined;
|
||||
|
||||
public decodeAddress = decodeAddress;
|
||||
|
||||
@@ -246,7 +246,7 @@ export class Keyring implements KeyringInstance {
|
||||
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
|
||||
return this.type === 'ethereum'
|
||||
? 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
|
||||
|
||||
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '11.1.3' };
|
||||
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '12.6.1' };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { EncryptedJsonEncoding, Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types.js';
|
||||
import type { PairInfo } from './types.js';
|
||||
@@ -165,7 +164,7 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
setMeta: (additional: KeyringPair$Meta): void => {
|
||||
meta = objectSpread({}, meta, additional);
|
||||
},
|
||||
sign: (message: HexString | string | Uint8Array, options: SignOptions = {}): Uint8Array => {
|
||||
sign: (message: string | Uint8Array, options: SignOptions = {}): Uint8Array => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot sign with a locked key pair');
|
||||
}
|
||||
@@ -192,10 +191,10 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
unlock: (passphrase?: string): void => {
|
||||
return decodePkcs8(passphrase);
|
||||
},
|
||||
verify: (message: HexString | string | Uint8Array, signature: HexString | string | Uint8Array, signerPublic: HexString | string | Uint8Array): boolean => {
|
||||
verify: (message: string | Uint8Array, signature: string | Uint8Array, signerPublic: string | Uint8Array): boolean => {
|
||||
return signatureVerify(message, signature, TYPE_ADDRESS[type](u8aToU8a(signerPublic))).isValid;
|
||||
},
|
||||
vrfSign: (message: HexString | string | Uint8Array, context?: HexString | string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
|
||||
vrfSign: (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot sign with a locked key pair');
|
||||
}
|
||||
@@ -208,7 +207,7 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
|
||||
return u8aConcat(vrfHash(proof, context, extra), proof);
|
||||
},
|
||||
vrfVerify: (message: HexString | string | Uint8Array, vrfResult: Uint8Array, signerPublic: HexString | Uint8Array | string, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): boolean => {
|
||||
vrfVerify: (message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: Uint8Array | string, context?: string | Uint8Array, extra?: string | Uint8Array): boolean => {
|
||||
if (type === 'sr25519') {
|
||||
return sr25519VrfVerify(message, vrfResult, publicKey, context, extra);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
export interface PairInfo {
|
||||
publicKey: Uint8Array;
|
||||
secretKey?: Uint8Array;
|
||||
secretKey?: Uint8Array | undefined;
|
||||
seed?: Uint8Array | null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { KeyringPair, KeyringPairs } from './types.js';
|
||||
|
||||
import { isHex, isU8a, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
@@ -22,7 +21,7 @@ export class Pairs implements KeyringPairs {
|
||||
return Object.values(this.#map);
|
||||
}
|
||||
|
||||
public get (address: HexString | string | Uint8Array): KeyringPair {
|
||||
public get (address: string | Uint8Array): KeyringPair {
|
||||
const pair = this.#map[decodeAddress(address).toString()];
|
||||
|
||||
if (!pair) {
|
||||
@@ -36,7 +35,7 @@ export class Pairs implements KeyringPairs {
|
||||
return pair;
|
||||
}
|
||||
|
||||
public remove (address: HexString | string | Uint8Array): void {
|
||||
public remove (address: string | Uint8Array): void {
|
||||
delete this.#map[decodeAddress(address).toString()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ describe('keyring.addFromUri', (): void => {
|
||||
for (const [type, tests] of Object.entries(TESTS)) {
|
||||
const keyring = new Keyring({ type: type as KeypairType });
|
||||
|
||||
describe(type, (): void => {
|
||||
describe(`${type}`, (): void => {
|
||||
tests.forEach(({ pk, ss, uri }): void => {
|
||||
it(`creates ${uri}`, (): void => {
|
||||
const pair = keyring.addFromUri(uri, {}, type as KeypairType);
|
||||
|
||||
@@ -119,7 +119,7 @@ function createMeta (name?: string, seed?: string) {
|
||||
|
||||
return {
|
||||
isTesting: true,
|
||||
name: name || (seed && seed.replace('//', '_').toLowerCase())
|
||||
name: name || seed?.replace('//', '_').toLowerCase()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -42,12 +42,10 @@ describe('testingPairs', (): void => {
|
||||
const keyring = new Keyring({ type: 'ethereum' });
|
||||
const pair = keyring.createFromUri('0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133');
|
||||
|
||||
expect(
|
||||
pair && pair.address
|
||||
).toEqual(TEST_ADD);
|
||||
expect(pair?.address).toEqual(TEST_ADD);
|
||||
});
|
||||
|
||||
it('checks eth test addresses', (): void => {
|
||||
describe('checks eth test addresses', (): void => {
|
||||
const ring = createTestPairs({ 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"
|
||||
@@ -62,12 +60,20 @@ describe('testingPairs', (): void => {
|
||||
'0x4c42532034540267bf568198ccec4cb822a025da542861fcb146a5fab6433ff8',
|
||||
'0x94c49300a58d576011096bcb006aa06f5a91b34b4383891e8029c21dc39fbb8b'];
|
||||
|
||||
// @ts-expect-error We should not delete from the maps, however this is a test
|
||||
delete ring.nobody;
|
||||
|
||||
Object.keys(ring).forEach((testKeyring, i) => {
|
||||
if (i < 6) {
|
||||
expect(u8aToHex(ring[testKeyring].publicKey)).toEqual(u8aToHex(keyring.createFromUri(privKeys[i]).publicKey));
|
||||
}
|
||||
});
|
||||
Object
|
||||
.keys(ring)
|
||||
.filter((_, i) => i < 6)
|
||||
.forEach((testKeyring, i) => {
|
||||
it(`checks #${i}`, (): void => {
|
||||
expect(
|
||||
u8aToHex(ring[testKeyring].publicKey)
|
||||
).toEqual(
|
||||
u8aToHex(keyring.createFromUri(privKeys[i]).publicKey)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,23 +1,56 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringOptions, KeyringPair } from './types.js';
|
||||
|
||||
import { nobody } from './pair/nobody.js';
|
||||
import { createTestKeyring } from './testing.js';
|
||||
|
||||
export interface TestKeyringMap {
|
||||
nobody: 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 pairs = keyring.getPairs();
|
||||
const map: TestKeyringMap = { nobody: nobody() };
|
||||
|
||||
for (const p of pairs) {
|
||||
map[p.meta.name as string] = p;
|
||||
if (p.meta.name) {
|
||||
map[p.meta.name] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
return map as M;
|
||||
}
|
||||
|
||||
@@ -5,29 +5,74 @@ import type { HexString } from '@polkadot/util/types';
|
||||
import type { EncryptedJson, Keypair, KeypairType, Prefix } from '@polkadot/util-crypto/types';
|
||||
|
||||
export interface KeyringOptions {
|
||||
/**
|
||||
* @description The ss58Format to use for address encoding (defaults to 42)
|
||||
*/
|
||||
/** The ss58Format to use for address encoding (defaults to 42) */
|
||||
ss58Format?: Prefix;
|
||||
/**
|
||||
* @description The type of keyring to create (defaults to ed25519)
|
||||
*/
|
||||
/** The type of keyring to create (defaults to ed25519) */
|
||||
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 {
|
||||
/** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */
|
||||
address: string | HexString;
|
||||
address: string;
|
||||
/** The underlying metadata associated with the keypair */
|
||||
meta: KeyringPair$Meta;
|
||||
}
|
||||
|
||||
export interface SignOptions {
|
||||
/**
|
||||
* @description Create a MultiSignature-compatible output with an indicator type
|
||||
**/
|
||||
/** Create a MultiSignature-compatible output with an indicator type */
|
||||
withType?: boolean;
|
||||
}
|
||||
|
||||
@@ -44,12 +89,12 @@ export interface KeyringPair {
|
||||
encodePkcs8 (passphrase?: string): Uint8Array;
|
||||
lock (): void;
|
||||
setMeta (meta: KeyringPair$Meta): void;
|
||||
sign (message: HexString | string | Uint8Array, options?: SignOptions): Uint8Array;
|
||||
sign (message: string | Uint8Array, options?: SignOptions): Uint8Array;
|
||||
toJson (passphrase?: string): KeyringPair$Json;
|
||||
unlock (passphrase?: string): void;
|
||||
verify (message: HexString | string | Uint8Array, signature: Uint8Array, signerPublic: HexString | string | Uint8Array): boolean;
|
||||
vrfSign (message: HexString | string | Uint8Array, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): Uint8Array;
|
||||
vrfVerify (message: HexString | string | Uint8Array, vrfResult: Uint8Array, signerPublic: HexString | Uint8Array | string, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): boolean;
|
||||
verify (message: string | Uint8Array, signature: Uint8Array, signerPublic: string | Uint8Array): boolean;
|
||||
vrfSign (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array;
|
||||
vrfVerify (message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean;
|
||||
}
|
||||
|
||||
export interface KeyringPairs {
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../util/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",
|
||||
"description": "A list of all available Substrate networks and their applicable prefixes",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
|
||||
"license": "Apache-2.0",
|
||||
@@ -15,14 +15,14 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@polkadot/util": "11.1.3",
|
||||
"@substrate/ss58-registry": "^1.39.0",
|
||||
"tslib": "^2.5.0"
|
||||
"@polkadot/util": "12.6.1",
|
||||
"@substrate/ss58-registry": "^1.44.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/hw-ledger": "11.1.3"
|
||||
"@polkadot/hw-ledger": "12.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,33 @@
|
||||
import { ledgerApps } from '@polkadot/hw-ledger/defaults';
|
||||
import { isHex } from '@polkadot/util';
|
||||
|
||||
import { knownGenesis, knownLedger } from './defaults/index.js';
|
||||
import { knownGenesis, knownLedger, knownTestnet } from './defaults/index.js';
|
||||
|
||||
describe('defaults', (): void => {
|
||||
const genesisKeys = Object.keys(knownGenesis);
|
||||
const ledgerKeys = Object.keys(knownLedger);
|
||||
|
||||
describe('genesis', (): void => {
|
||||
it('has hex values for all genesis chains', (): void => {
|
||||
expect(
|
||||
Object.keys(knownGenesis).filter((network) =>
|
||||
genesisKeys.filter((network) =>
|
||||
!knownGenesis[network].length ||
|
||||
knownGenesis[network].some((g) => !isHex(g, 256))
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('has no entries for testnets', (): void => {
|
||||
expect(
|
||||
genesisKeys.filter((network) =>
|
||||
knownTestnet[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('has genesis for all Ledger chains', (): void => {
|
||||
expect(
|
||||
Object.keys(knownLedger).filter((network) =>
|
||||
ledgerKeys.filter((network) =>
|
||||
!knownGenesis[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
@@ -31,7 +42,7 @@ describe('defaults', (): void => {
|
||||
describe('Ledger', (): void => {
|
||||
it('has entries for each of the apps (hwledger -> networks)', (): void => {
|
||||
expect(
|
||||
Object.keys(knownLedger).filter((network) =>
|
||||
ledgerKeys.filter((network) =>
|
||||
!ledgerApps[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
|
||||
import type { KnownGenesis } from '../types.js';
|
||||
|
||||
// NOTE: In the case where the network was hard-spooned and multiple genesisHashes
|
||||
// are provided, it needs to be in reverse order, i.e. most-recent first, oldest
|
||||
// last. This make lookups for the current a simple genesisHash[0]
|
||||
// (See Kusama as an example)
|
||||
// In the case where the network was hard-spooned and multiple genesisHashes
|
||||
// are provided, it needs to be in reverse order, i.e. most-recent goes first,
|
||||
// oldest goes last. This make lookups for the current a simple genesisHash[0]
|
||||
// where the latest ios always the first entry (See Kusama as an example)
|
||||
//
|
||||
// IMPORTANT: Apart from the test relays, this list is limited to live parachains
|
||||
// and live production networks. It does not and should not contain any testnets,
|
||||
// either stand-alone or connected to test relays such as Westend/Rococo
|
||||
export const knownGenesis: KnownGenesis = {
|
||||
acala: [
|
||||
'0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c'
|
||||
@@ -36,6 +40,9 @@ export const knownGenesis: KnownGenesis = {
|
||||
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
|
||||
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
|
||||
],
|
||||
cere: [
|
||||
'0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c'
|
||||
],
|
||||
composable: [
|
||||
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
|
||||
],
|
||||
@@ -49,6 +56,9 @@ export const knownGenesis: KnownGenesis = {
|
||||
edgeware: [
|
||||
'0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b'
|
||||
],
|
||||
enjin: [
|
||||
'0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9'
|
||||
],
|
||||
equilibrium: [
|
||||
'0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925'
|
||||
],
|
||||
@@ -79,6 +89,9 @@ export const knownGenesis: KnownGenesis = {
|
||||
'0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2
|
||||
'0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' // Kusama CC1
|
||||
],
|
||||
matrixchain: [
|
||||
'0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615'
|
||||
],
|
||||
nodle: [
|
||||
'0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21'
|
||||
],
|
||||
@@ -110,6 +123,9 @@ export const knownGenesis: KnownGenesis = {
|
||||
polymesh: [
|
||||
'0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063'
|
||||
],
|
||||
quartz: [
|
||||
'0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554'
|
||||
],
|
||||
rococo: [
|
||||
'0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e',
|
||||
'0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897',
|
||||
@@ -154,5 +170,8 @@ export const knownGenesis: KnownGenesis = {
|
||||
],
|
||||
xxnetwork: [
|
||||
'0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa'
|
||||
],
|
||||
zeitgeist: [
|
||||
'0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060'
|
||||
]
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ export const knownLedger: KnownLedger = {
|
||||
darwinia: 0x00000162,
|
||||
'dock-mainnet': 0x00000252,
|
||||
edgeware: 0x0000020b,
|
||||
enjin: 0x00000483,
|
||||
equilibrium: 0x05f5e0fd,
|
||||
genshiro: 0x05f5e0fc,
|
||||
hydradx: 0x00000162,
|
||||
@@ -26,6 +27,7 @@ export const knownLedger: KnownLedger = {
|
||||
karura: 0x000002ae,
|
||||
khala: 0x000001b2,
|
||||
kusama: 0x000001b2,
|
||||
matrixchain: 0x00000483,
|
||||
nodle: 0x000003eb,
|
||||
origintrail: 0x00000162,
|
||||
parallel: 0x00000162,
|
||||
@@ -35,12 +37,14 @@ export const knownLedger: KnownLedger = {
|
||||
polkadex: 0x0000031f,
|
||||
polkadot: 0x00000162,
|
||||
polymesh: 0x00000253,
|
||||
quartz: 0x00000277,
|
||||
sora: 0x00000269,
|
||||
stafi: 0x0000038b,
|
||||
statemine: 0x000001b2, // common-good on Kusama, shares derivation
|
||||
statemint: 0x00000162, // common-good on Polkadot, shares derivation
|
||||
ternoa: 0x00003e3,
|
||||
unique: 0x00000162,
|
||||
unique: 0x00000295,
|
||||
vtb: 0x000002b6,
|
||||
xxnetwork: 0x000007a3
|
||||
xxnetwork: 0x000007a3,
|
||||
zeitgeist: 0x00000162
|
||||
};
|
||||
|
||||
@@ -115,6 +115,6 @@ describe('selectableNetworks', (): void => {
|
||||
|
||||
it('has a sorted list (first external, last external)', (): void => {
|
||||
expect(selectableNetworks[3].displayName).toEqual('3DP network');
|
||||
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('xx network');
|
||||
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('Zeitgeist');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,8 +29,8 @@ function toExpanded (o: KnownSubstrate): SubstrateNetwork {
|
||||
n.isIgnored = n.isTestnet || (
|
||||
!(
|
||||
o.standardAccount &&
|
||||
o.decimals && o.decimals.length &&
|
||||
o.symbols && o.symbols.length
|
||||
o.decimals?.length &&
|
||||
o.symbols?.length
|
||||
) &&
|
||||
o.prefix !== 42
|
||||
);
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/networks', path: 'auto', type: 'auto', version: '11.1.3' };
|
||||
export const packageInfo = { name: '@polkadot/networks', path: 'auto', type: 'auto', version: '12.6.1' };
|
||||
|
||||
@@ -5,24 +5,30 @@
|
||||
|
||||
import known from '@substrate/ss58-registry';
|
||||
import fs from 'node:fs';
|
||||
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;
|
||||
import { stringify } from '@polkadot/util';
|
||||
|
||||
describe('@substrate/ss58-registry', (): void => {
|
||||
it('has known values', (): void => {
|
||||
const json = JSON.stringify(known, null, 2);
|
||||
const testUrl = new URL('../test/ss58registry.json', import.meta.url);
|
||||
const json = stringify(known, 2);
|
||||
|
||||
try {
|
||||
expect(JSON.parse(json)).toEqual(other);
|
||||
expect(
|
||||
JSON.parse(json)
|
||||
).toEqual(
|
||||
JSON.parse(
|
||||
fs.readFileSync(testUrl, 'utf-8')
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
if (process.env.GITHUB_REPOSITORY) {
|
||||
if (process.env['GITHUB_REPOSITORY']) {
|
||||
console.error(json);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(process.cwd(), 'packages/networks/src/test/ss58registry.test.json'), json, { flag: 'w' });
|
||||
fs.writeFileSync(testUrl, json, { flag: 'w' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { RegistryEntry } from '@substrate/ss58-registry';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
export type Icon = 'beachball' | 'empty' | 'jdenticon' | 'polkadot' | 'substrate';
|
||||
|
||||
@@ -9,22 +10,29 @@ export type KnownIcon = Record<string, Icon>;
|
||||
|
||||
export type KnownLedger = Record<string, number>;
|
||||
|
||||
export type KnownGenesis = Record<string, string[]>;
|
||||
export type KnownGenesis = Record<string, HexString[]>;
|
||||
|
||||
export type KnownSubstrate = RegistryEntry;
|
||||
|
||||
export type KnownTestnet = Record<string, true>;
|
||||
|
||||
export interface SubstrateNetwork extends KnownSubstrate {
|
||||
genesisHash: string[];
|
||||
/** The genesisHash for the chain */
|
||||
genesisHash: HexString[];
|
||||
/** Does the chain has support for Ledger devices */
|
||||
hasLedgerSupport: boolean;
|
||||
/** The IdentityIcon to use for the chain */
|
||||
icon: Icon;
|
||||
/** Flag set when we don't include this chain */
|
||||
isIgnored: boolean;
|
||||
/** Flag to indicate a testnet */
|
||||
isTestnet: boolean;
|
||||
/** The Ledger-specific/required slip44 for the chain */
|
||||
slip44?: number | null;
|
||||
}
|
||||
|
||||
export interface Network extends SubstrateNetwork {
|
||||
/** The network assigned to this chain */
|
||||
network: string;
|
||||
}
|
||||
|
||||
|
||||
+171
-13
@@ -222,15 +222,13 @@
|
||||
"network": "darwinia",
|
||||
"displayName": "Darwinia Network",
|
||||
"symbols": [
|
||||
"RING",
|
||||
"KTON"
|
||||
"RING"
|
||||
],
|
||||
"decimals": [
|
||||
9,
|
||||
9
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://darwinia.network/"
|
||||
"standardAccount": "secp256k1",
|
||||
"website": "https://darwinia.network"
|
||||
},
|
||||
{
|
||||
"prefix": 19,
|
||||
@@ -258,6 +256,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://stafi.io"
|
||||
},
|
||||
{
|
||||
"prefix": 21,
|
||||
"network": "karmachain",
|
||||
"displayName": "Karmacoin",
|
||||
"symbols": [
|
||||
"KCOIN"
|
||||
],
|
||||
"decimals": [
|
||||
6
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://karmaco.in"
|
||||
},
|
||||
{
|
||||
"prefix": 22,
|
||||
"network": "dock-pos-mainnet",
|
||||
@@ -497,12 +508,16 @@
|
||||
},
|
||||
{
|
||||
"prefix": 41,
|
||||
"network": "poli",
|
||||
"displayName": "Polimec Chain",
|
||||
"symbols": [],
|
||||
"decimals": [],
|
||||
"network": "polimec",
|
||||
"displayName": "Polimec Protocol",
|
||||
"symbols": [
|
||||
"PLMC"
|
||||
],
|
||||
"decimals": [
|
||||
10
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://polimec.io/"
|
||||
"website": "https://www.polimec.org/"
|
||||
},
|
||||
{
|
||||
"prefix": 42,
|
||||
@@ -597,7 +612,7 @@
|
||||
{
|
||||
"prefix": 50,
|
||||
"network": "composable",
|
||||
"displayName": "Composable",
|
||||
"displayName": "Composable Finance",
|
||||
"symbols": [
|
||||
"LAYR"
|
||||
],
|
||||
@@ -713,10 +728,23 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://hydradx.io"
|
||||
},
|
||||
{
|
||||
"prefix": 64,
|
||||
"network": "ewx",
|
||||
"displayName": "Energy Web X",
|
||||
"symbols": [
|
||||
"EWT"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://www.energyweb.org"
|
||||
},
|
||||
{
|
||||
"prefix": 65,
|
||||
"network": "aventus",
|
||||
"displayName": "AvN Mainnet",
|
||||
"displayName": "Aventus Mainnet",
|
||||
"symbols": [
|
||||
"AVT"
|
||||
],
|
||||
@@ -1168,6 +1196,32 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://sora.org"
|
||||
},
|
||||
{
|
||||
"prefix": 440,
|
||||
"network": "allfeat_network",
|
||||
"displayName": "Allfeat Network",
|
||||
"symbols": [
|
||||
"AFT"
|
||||
],
|
||||
"decimals": [
|
||||
12
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://allfeat.network"
|
||||
},
|
||||
{
|
||||
"prefix": 666,
|
||||
"network": "metaquity_network",
|
||||
"displayName": "Metaquity Network",
|
||||
"symbols": [
|
||||
"MQTY"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://metaquity.xyz/"
|
||||
},
|
||||
{
|
||||
"prefix": 789,
|
||||
"network": "geek",
|
||||
@@ -1337,6 +1391,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"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,
|
||||
"network": "interlay",
|
||||
@@ -1389,6 +1456,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://chainflip.io/"
|
||||
},
|
||||
{
|
||||
"prefix": 2199,
|
||||
"network": "moonsama",
|
||||
"displayName": "Moonsama",
|
||||
"symbols": [
|
||||
"SAMA"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "secp256k1",
|
||||
"website": "https://moonsama.com"
|
||||
},
|
||||
{
|
||||
"prefix": 2206,
|
||||
"network": "ICE",
|
||||
@@ -1428,6 +1508,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://subspace.network"
|
||||
},
|
||||
{
|
||||
"prefix": 3333,
|
||||
"network": "peerplays",
|
||||
"displayName": "Peerplays",
|
||||
"symbols": [
|
||||
"PPY"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "secp256k1",
|
||||
"website": "https://www.peerplays.com/"
|
||||
},
|
||||
{
|
||||
"prefix": 4006,
|
||||
"network": "tangle",
|
||||
@@ -1510,6 +1603,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://gmordie.com"
|
||||
},
|
||||
{
|
||||
"prefix": 7306,
|
||||
"network": "krigan",
|
||||
"displayName": "Krigan Network",
|
||||
"symbols": [
|
||||
"KRGN"
|
||||
],
|
||||
"decimals": [
|
||||
9
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://krigan.network"
|
||||
},
|
||||
{
|
||||
"prefix": 7391,
|
||||
"network": "unique_mainnet",
|
||||
@@ -1523,6 +1629,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://unique.network"
|
||||
},
|
||||
{
|
||||
"prefix": 8866,
|
||||
"network": "golden_gate",
|
||||
"displayName": "Golden Gate",
|
||||
"symbols": [
|
||||
"GGX"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://ggxchain.io/"
|
||||
},
|
||||
{
|
||||
"prefix": 8883,
|
||||
"network": "sapphire_mainnet",
|
||||
@@ -1536,6 +1655,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://unique.network"
|
||||
},
|
||||
{
|
||||
"prefix": 8886,
|
||||
"network": "golden_gate_sydney",
|
||||
"displayName": "Golden Gate Sydney",
|
||||
"symbols": [
|
||||
"GGXT"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://ggxchain.io/"
|
||||
},
|
||||
{
|
||||
"prefix": 9072,
|
||||
"network": "hashed",
|
||||
@@ -1640,6 +1772,19 @@
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://ata.network"
|
||||
},
|
||||
{
|
||||
"prefix": 12155,
|
||||
"network": "impact",
|
||||
"displayName": "Impact Protocol Network",
|
||||
"symbols": [
|
||||
"BSTY"
|
||||
],
|
||||
"decimals": [
|
||||
18
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://impactprotocol.network/"
|
||||
},
|
||||
{
|
||||
"prefix": 12191,
|
||||
"network": "nftmart",
|
||||
@@ -1665,5 +1810,18 @@
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://bittensor.com"
|
||||
},
|
||||
{
|
||||
"prefix": 14697,
|
||||
"network": "goro",
|
||||
"displayName": "GORO Network",
|
||||
"symbols": [
|
||||
"GORO"
|
||||
],
|
||||
"decimals": [
|
||||
9
|
||||
],
|
||||
"standardAccount": "*25519",
|
||||
"website": "https://goro.network"
|
||||
}
|
||||
]
|
||||
@@ -5,9 +5,10 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": [
|
||||
"**/src/**/*.ts",
|
||||
"**/test/*.json"
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/test/*",
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "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",
|
||||
"description": "A collection of useful crypto utilities for @polkadot",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,25 +20,25 @@
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "11.1.3",
|
||||
"version": "12.6.1",
|
||||
"browser": {
|
||||
"crypto": false,
|
||||
"stream": false
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.0",
|
||||
"@noble/secp256k1": "1.7.1",
|
||||
"@polkadot/networks": "11.1.3",
|
||||
"@polkadot/util": "11.1.3",
|
||||
"@polkadot/wasm-crypto": "^7.0.3",
|
||||
"@polkadot/x-bigint": "11.1.3",
|
||||
"@polkadot/x-randomvalues": "11.1.3",
|
||||
"@scure/base": "1.1.1",
|
||||
"tslib": "^2.5.0",
|
||||
"tweetnacl": "^1.0.3"
|
||||
"@noble/curves": "^1.2.0",
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@polkadot/networks": "12.6.1",
|
||||
"@polkadot/util": "12.6.1",
|
||||
"@polkadot/wasm-crypto": "^7.3.1",
|
||||
"@polkadot/wasm-util": "^7.3.1",
|
||||
"@polkadot/x-bigint": "12.6.1",
|
||||
"@polkadot/x-randomvalues": "12.6.1",
|
||||
"@scure/base": "^1.1.3",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@polkadot/util": "11.1.3"
|
||||
"@polkadot/util": "12.6.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { decodeAddress } from './decode.js';
|
||||
|
||||
/**
|
||||
* @name addressToEvm
|
||||
* @summary Converts an SS58 address to its corresponding EVM address.
|
||||
*/
|
||||
export function addressToEvm (address: HexString | string | Uint8Array, ignoreChecksum?: boolean): Uint8Array {
|
||||
export function addressToEvm (address: string | Uint8Array, ignoreChecksum?: boolean): Uint8Array {
|
||||
return decodeAddress(address, ignoreChecksum).subarray(0, 20);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { base58Decode } from '../base58/index.js';
|
||||
@@ -14,7 +13,7 @@ import { defaults } from './defaults.js';
|
||||
* @description
|
||||
* From the provided input, validate that the address is a valid input.
|
||||
*/
|
||||
export function checkAddress (address: HexString | string, prefix: Prefix): [boolean, string | null] {
|
||||
export function checkAddress (address: string, prefix: Prefix): [boolean, string | null] {
|
||||
let decoded;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L6
|
||||
@@ -11,7 +10,7 @@ import { base58Decode } from '../base58/index.js';
|
||||
import { checkAddressChecksum } from './checksum.js';
|
||||
import { defaults } from './defaults.js';
|
||||
|
||||
export function decodeAddress (encoded?: HexString | string | Uint8Array | null, ignoreChecksum?: boolean, ss58Format: Prefix = -1): Uint8Array {
|
||||
export function decodeAddress (encoded?: string | Uint8Array | null, ignoreChecksum?: boolean, ss58Format: Prefix = -1): Uint8Array {
|
||||
if (!encoded) {
|
||||
throw new Error('Invalid empty address passed');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { DeriveJunction } from '../key/DeriveJunction.js';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
@@ -20,7 +19,7 @@ function filterHard ({ isHard }: DeriveJunction): boolean {
|
||||
* @description
|
||||
* Creates a sr25519 derived address based on the input address/publicKey and the uri supplied.
|
||||
*/
|
||||
export function deriveAddress (who: HexString | Uint8Array | string, suri: string, ss58Format?: Prefix): string {
|
||||
export function deriveAddress (who: string | Uint8Array, suri: string, ss58Format?: Prefix): string {
|
||||
const { path } = keyExtractPath(suri);
|
||||
|
||||
if (!path.length || path.every(filterHard)) {
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
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]);
|
||||
|
||||
// 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]);
|
||||
|
||||
const SUBKEY = [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L34
|
||||
@@ -12,7 +11,7 @@ import { decodeAddress } from './decode.js';
|
||||
import { defaults } from './defaults.js';
|
||||
import { sshash } from './sshash.js';
|
||||
|
||||
export function encodeAddress (key: HexString | Uint8Array | string, ss58Format: Prefix = defaults.prefix): string {
|
||||
export function encodeAddress (key: string | Uint8Array, ss58Format: Prefix = defaults.prefix): string {
|
||||
// decode it, this means we can re-encode an address
|
||||
const u8a = decodeAddress(key);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { decodeAddress } from './decode.js';
|
||||
@@ -15,6 +14,6 @@ import { createKeyDerived } from './keyDerived.js';
|
||||
* @description
|
||||
* Creates a Substrate derived address based on the input address/publicKey and the index supplied.
|
||||
*/
|
||||
export function encodeDerivedAddress (who: HexString | Uint8Array | string, index: bigint | BN | number, ss58Format?: Prefix): string {
|
||||
export function encodeDerivedAddress (who: string | Uint8Array, index: bigint | BN | number, ss58Format?: Prefix): string {
|
||||
return encodeAddress(createKeyDerived(decodeAddress(who), index), ss58Format);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { encodeAddress } from './encode.js';
|
||||
@@ -14,6 +13,6 @@ import { createKeyMulti } from './keyMulti.js';
|
||||
* @description
|
||||
* Creates a Substrate multisig address based on the input address and the required threshold.
|
||||
*/
|
||||
export function encodeMultiAddress (who: (HexString | Uint8Array | string)[], threshold: bigint | BN | number, ss58Format?: Prefix): string {
|
||||
export function encodeMultiAddress (who: (string | Uint8Array)[], threshold: bigint | BN | number, ss58Format?: Prefix): string {
|
||||
return encodeAddress(createKeyMulti(who, threshold), ss58Format);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { u8aEq } from '@polkadot/util';
|
||||
|
||||
import { decodeAddress } from './decode.js';
|
||||
@@ -21,6 +19,6 @@ import { decodeAddress } from './decode.js';
|
||||
* u8aEq(new Uint8Array([0x68, 0x65]), new Uint8Array([0x68, 0x65])); // true
|
||||
* ```
|
||||
*/
|
||||
export function addressEq (a: HexString | string | Uint8Array, b: HexString | string | Uint8Array): boolean {
|
||||
export function addressEq (a: string | Uint8Array, b: string | Uint8Array): boolean {
|
||||
return u8aEq(decodeAddress(a), decodeAddress(b));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { HashType } from '../secp256k1/types.js';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
@@ -14,7 +13,7 @@ import { encodeAddress } from './encode.js';
|
||||
* @name evmToAddress
|
||||
* @summary Converts an EVM address to its corresponding SS58 address.
|
||||
*/
|
||||
export function evmToAddress (evmAddress: HexString | string | Uint8Array, ss58Format?: Prefix, hashType: HashType = 'blake2'): string {
|
||||
export function evmToAddress (evmAddress: string | Uint8Array, ss58Format?: Prefix, hashType: HashType = 'blake2'): string {
|
||||
const message = u8aConcat('evm:', evmAddress);
|
||||
|
||||
if (message.length !== 24) {
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
export { addressToEvm } from './addressToEvm.js';
|
||||
export { checkAddress } from './check.js';
|
||||
export { checkAddressChecksum } from './checksum.js';
|
||||
export { createKeyMulti } from './keyMulti.js';
|
||||
export { createKeyDerived } from './keyDerived.js';
|
||||
export { decodeAddress } from './decode.js';
|
||||
export { deriveAddress } from './derive.js';
|
||||
export { encodeAddress } from './encode.js';
|
||||
export { encodeDerivedAddress } from './encodeDerived.js';
|
||||
export { encodeMultiAddress } from './encodeMulti.js';
|
||||
export { evmToAddress } from './evmToAddress.js';
|
||||
export { addressEq } from './eq.js';
|
||||
export { evmToAddress } from './evmToAddress.js';
|
||||
export { isAddress } from './is.js';
|
||||
export { createKeyDerived } from './keyDerived.js';
|
||||
export { createKeyMulti } from './keyMulti.js';
|
||||
export { sortAddresses } from './sort.js';
|
||||
export { validateAddress } from './validate.js';
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { validateAddress } from './validate.js';
|
||||
|
||||
export function isAddress (address?: HexString | string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): address is string {
|
||||
export function isAddress (address?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): address is string {
|
||||
try {
|
||||
return validateAddress(address, ignoreChecksum, ss58Format);
|
||||
} catch {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
||||
|
||||
@@ -12,7 +11,7 @@ import { decodeAddress } from './decode.js';
|
||||
|
||||
const PREFIX = stringToU8a('modlpy/utilisuba');
|
||||
|
||||
export function createKeyDerived (who: HexString | Uint8Array | string, index: bigint | BN | number): Uint8Array {
|
||||
export function createKeyDerived (who: string | Uint8Array, index: bigint | BN | number): Uint8Array {
|
||||
return blake2AsU8a(
|
||||
u8aConcat(
|
||||
PREFIX,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { bnToU8a, compactToU8a, stringToU8a, u8aConcat, u8aSorted } from '@polkadot/util';
|
||||
|
||||
@@ -12,7 +11,7 @@ import { addressToU8a } from './util.js';
|
||||
|
||||
const PREFIX = stringToU8a('modlpy/utilisuba');
|
||||
|
||||
export function createKeyMulti (who: (HexString | Uint8Array | string)[], threshold: bigint | BN | number): Uint8Array {
|
||||
export function createKeyMulti (who: (string | Uint8Array)[], threshold: bigint | BN | number): Uint8Array {
|
||||
return blake2AsU8a(
|
||||
u8aConcat(
|
||||
PREFIX,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { u8aSorted } from '@polkadot/util';
|
||||
@@ -9,7 +8,7 @@ import { u8aSorted } from '@polkadot/util';
|
||||
import { encodeAddress } from './encode.js';
|
||||
import { addressToU8a } from './util.js';
|
||||
|
||||
export function sortAddresses (addresses: (HexString | Uint8Array | string)[], ss58Format?: Prefix): string[] {
|
||||
export function sortAddresses (addresses: (string | Uint8Array)[], ss58Format?: Prefix): string[] {
|
||||
const u8aToAddress = (u8a: Uint8Array) => encodeAddress(u8a, ss58Format);
|
||||
|
||||
return u8aSorted(
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { Prefix } from './types.js';
|
||||
|
||||
import { decodeAddress } from './decode.js';
|
||||
|
||||
export function validateAddress (encoded?: HexString | string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): encoded is string {
|
||||
export function validateAddress (encoded?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): encoded is string {
|
||||
return !!decodeAddress(encoded, ignoreChecksum, ss58Format);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ interface Config {
|
||||
ipfs?: string;
|
||||
regex?: RegExp;
|
||||
type: string;
|
||||
withPadding?: boolean;
|
||||
}
|
||||
|
||||
type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array;
|
||||
@@ -63,21 +64,26 @@ export function createIs (validate: ValidateFn): ValidateFn {
|
||||
}
|
||||
|
||||
/** @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 => {
|
||||
if (typeof value !== 'string') {
|
||||
throw new Error(`Expected ${type} string input`);
|
||||
} else if (ipfs && ipfsCompat && value[0] !== ipfs) {
|
||||
} else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) {
|
||||
throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
|
||||
}
|
||||
|
||||
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
|
||||
if (!(chars.includes(value[i]) || (
|
||||
value[i] === '=' && (
|
||||
(i === value.length - 1) ||
|
||||
!chars.includes(value[i + 1])
|
||||
)
|
||||
))) {
|
||||
for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) {
|
||||
if (chars.includes(value[i])) {
|
||||
// all ok, character found
|
||||
} else if (withPadding && value[i] === '=') {
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||
coder: base64,
|
||||
type: 'base64'
|
||||
type: 'base64',
|
||||
withPadding: true
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description Trims padding characters
|
||||
*/
|
||||
export function base64Trim (value: string): string {
|
||||
while (value.length && value[value.length - 1] === '=') {
|
||||
while (value.length && value.endsWith('=')) {
|
||||
value = value.slice(0, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,4 +11,22 @@ describe('base64Validate', (): void => {
|
||||
() => base64Validate('aGVsbG8gd29ybGQg0J/RgNC40LLQtd^GC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
|
||||
).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"/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { blake2b as blake2bJs } from '@noble/hashes/blake2b';
|
||||
|
||||
import { hasBigInt, u8aToU8a } from '@polkadot/util';
|
||||
@@ -24,13 +22,15 @@ import { createAsHex } from '../helpers.js';
|
||||
* blake2AsU8a('abc'); // => [0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d]
|
||||
* ```
|
||||
*/
|
||||
export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength: 64 | 128 | 256 | 384 | 512 = 256, key?: Uint8Array | null, onlyJs?: boolean): Uint8Array {
|
||||
export function blake2AsU8a (data: string | Uint8Array, bitLength: 64 | 128 | 256 | 384 | 512 = 256, key?: Uint8Array | null, onlyJs?: boolean): Uint8Array {
|
||||
const byteLength = Math.ceil(bitLength / 8);
|
||||
const u8a = u8aToU8a(data);
|
||||
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
? blake2b(u8a, u8aToU8a(key), byteLength)
|
||||
: blake2bJs(u8a, { dkLen: byteLength, key: key || undefined });
|
||||
: key
|
||||
? blake2bJs(u8a, { dkLen: byteLength, key })
|
||||
: blake2bJs(u8a, { dkLen: byteLength });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
import './bundleInit.js';
|
||||
|
||||
// all named
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
// all internal exports
|
||||
// all starred
|
||||
export * from './address/index.js';
|
||||
export * from './base32/index.js';
|
||||
export * from './base58/index.js';
|
||||
@@ -20,8 +21,8 @@ export * from './json/index.js';
|
||||
export * from './keccak/index.js';
|
||||
export * from './key/index.js';
|
||||
export * from './mnemonic/index.js';
|
||||
export * from './networks.js';
|
||||
export * from './nacl/index.js';
|
||||
export * from './networks.js';
|
||||
export * from './pbkdf2/index.js';
|
||||
export * from './random/index.js';
|
||||
export * from './scrypt/index.js';
|
||||
|
||||
@@ -3,18 +3,8 @@
|
||||
|
||||
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';
|
||||
|
||||
// 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
|
||||
cryptoWaitReady().catch((): void => {
|
||||
// shouldn't happen, logged and caught inside cryptoWaitReady
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
// no TS, this is not meant to be a global...
|
||||
export {};
|
||||
|
||||
describe('cryptoWaitReady', (): void => {
|
||||
it('should return false when it cannot initialize', async (): Promise<void> => {
|
||||
const old = global.WebAssembly;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
import type { Keypair } from '../../types.js';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
/**
|
||||
* @name ed25519PairFromSecret
|
||||
* @summary Creates a new public/secret keypair from a secret.
|
||||
@@ -19,6 +17,13 @@ import nacl from 'tweetnacl';
|
||||
* ed25519PairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export function ed25519PairFromSecret (secret: Uint8Array): Keypair {
|
||||
return nacl.sign.keyPair.fromSecretKey(secret);
|
||||
export function ed25519PairFromSecret (secretKey: Uint8Array): Keypair {
|
||||
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 nacl from 'tweetnacl';
|
||||
import { ed25519 } from '@noble/curves/ed25519';
|
||||
|
||||
import { hasBigInt, u8aConcatStrict } from '@polkadot/util';
|
||||
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 {
|
||||
if (!onlyJs && isReady()) {
|
||||
if (!hasBigInt || (!onlyJs && isReady())) {
|
||||
const full = ed25519KeypairFromSeed(seed);
|
||||
|
||||
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])
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
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';
|
||||
|
||||
/**
|
||||
@@ -23,14 +22,17 @@ import { ed25519Sign as wasmSign, isReady } from '@polkadot/wasm-crypto';
|
||||
* ed25519Sign([...], [...]); // => [...]
|
||||
* ```
|
||||
*/
|
||||
export function ed25519Sign (message: HexString | Uint8Array | string, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
|
||||
export function ed25519Sign (message: string | Uint8Array, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
|
||||
if (!secretKey) {
|
||||
throw new Error('Expected a valid secretKey');
|
||||
} else if (!publicKey) {
|
||||
throw new Error('Expected a valid publicKey');
|
||||
}
|
||||
|
||||
const messageU8a = u8aToU8a(message);
|
||||
const privateU8a = secretKey.subarray(0, 32);
|
||||
|
||||
return !onlyJs && isReady()
|
||||
? wasmSign(publicKey as Uint8Array, secretKey.subarray(0, 32), messageU8a)
|
||||
: nacl.sign.detached(messageU8a, secretKey);
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
? wasmSign(publicKey, privateU8a, messageU8a)
|
||||
: ed25519.sign(messageU8a, privateU8a);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import { ed25519 } from '@noble/curves/ed25519';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
import { u8aToU8a } from '@polkadot/util';
|
||||
import { hasBigInt, u8aToU8a } from '@polkadot/util';
|
||||
import { ed25519Verify as wasmVerify, isReady } from '@polkadot/wasm-crypto';
|
||||
|
||||
/**
|
||||
@@ -22,7 +20,7 @@ import { ed25519Verify as wasmVerify, isReady } from '@polkadot/wasm-crypto';
|
||||
* ed25519Verify([...], [...], [...]); // => true/false
|
||||
* ```
|
||||
*/
|
||||
export function ed25519Verify (message: HexString | Uint8Array | string, signature: HexString | Uint8Array | string, publicKey: HexString | Uint8Array | string, onlyJs?: boolean): boolean {
|
||||
export function ed25519Verify (message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array, onlyJs?: boolean): boolean {
|
||||
const messageU8a = u8aToU8a(message);
|
||||
const publicKeyU8a = u8aToU8a(publicKey);
|
||||
const signatureU8a = u8aToU8a(signature);
|
||||
@@ -33,7 +31,11 @@ export function ed25519Verify (message: HexString | Uint8Array | string, signatu
|
||||
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
||||
}
|
||||
|
||||
return !onlyJs && isReady()
|
||||
? wasmVerify(signatureU8a, messageU8a, publicKeyU8a)
|
||||
: nacl.sign.detached.verify(messageU8a, signatureU8a, publicKeyU8a);
|
||||
try {
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
? wasmVerify(signatureU8a, messageU8a, publicKeyU8a)
|
||||
: ed25519.verify(signatureU8a, messageU8a, publicKeyU8a);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ function getH160 (u8a: Uint8Array): Uint8Array {
|
||||
return u8a.slice(-20);
|
||||
}
|
||||
|
||||
export function ethereumEncode (addressOrPublic?: HexString | string | Uint8Array): HexString {
|
||||
export function ethereumEncode (addressOrPublic?: string | Uint8Array): HexString {
|
||||
if (!addressOrPublic) {
|
||||
return '0x';
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { isHex } from '@polkadot/util';
|
||||
|
||||
import { isEthereumChecksum } from './isChecksum.js';
|
||||
|
||||
export function isEthereumAddress (address?: HexString | string): boolean {
|
||||
export function isEthereumAddress (address?: string): boolean {
|
||||
if (!address || address.length !== 42 || !isHex(address)) {
|
||||
return false;
|
||||
} else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) {
|
||||
|
||||
@@ -21,14 +21,14 @@ export function createAsHex <T extends (...args: never[]) => Uint8Array> (fn: T)
|
||||
}
|
||||
|
||||
/** @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 {
|
||||
return (data: HexString | Buffer | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
|
||||
export function createBitHasher (bitLength: 256 | 512, fn: (data: string | Uint8Array, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: string | Uint8Array, onlyJs?: boolean) => Uint8Array {
|
||||
return (data: string | Uint8Array, onlyJs?: boolean): Uint8Array =>
|
||||
fn(data, bitLength, onlyJs);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createDualHasher (wa: DualHash, js: DualHash): (value: HexString | Buffer | Uint8Array | string, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array {
|
||||
return (value: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs?: boolean): Uint8Array => {
|
||||
export function createDualHasher (wa: DualHash, js: DualHash): (value: string | Uint8Array, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array {
|
||||
return (value: string | Uint8Array, bitLength: 256 | 512 = 256, onlyJs?: boolean): Uint8Array => {
|
||||
const u8a = u8aToU8a(value);
|
||||
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { hmacShaAsU8a, hmacSha256AsU8a, hmacSha512AsU8a } from './shaAsU8a.js';
|
||||
export { hmacSha256AsU8a, hmacSha512AsU8a, hmacShaAsU8a } from './shaAsU8a.js';
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
export type EncryptedJsonVersion = '0' | '1' | '2' | '3';
|
||||
|
||||
export type EncryptedJsonEncoding = 'none' | 'scrypt' | 'xsalsa20-poly1305';
|
||||
|
||||
export interface EncryptedJsonDescriptor {
|
||||
/** Descriptor for the content */
|
||||
content: string[];
|
||||
/** The encoding (in current/latest versions this is always an array) */
|
||||
type: EncryptedJsonEncoding | EncryptedJsonEncoding[];
|
||||
/** The version of encoding applied */
|
||||
version: EncryptedJsonVersion;
|
||||
}
|
||||
|
||||
export interface EncryptedJson {
|
||||
encoded: HexString | string;
|
||||
/** The encoded string */
|
||||
encoded: string;
|
||||
/** The encoding used */
|
||||
encoding: EncryptedJsonDescriptor;
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
* @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';
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
import { BN, bnToU8a, compactAddLength, hexToU8a, isBigInt, isBn, isHex, isNumber, isString, stringToU8a } from '@polkadot/util';
|
||||
|
||||
import { blake2AsU8a } from '../blake2/asU8a.js';
|
||||
@@ -46,7 +44,7 @@ export class DeriveJunction {
|
||||
return !this.#isHard;
|
||||
}
|
||||
|
||||
public hard (value: HexString | number | string | bigint | BN | Uint8Array): DeriveJunction {
|
||||
public hard (value: number | string | bigint | BN | Uint8Array): DeriveJunction {
|
||||
return this.soft(value).harden();
|
||||
}
|
||||
|
||||
@@ -56,7 +54,7 @@ export class DeriveJunction {
|
||||
return this;
|
||||
}
|
||||
|
||||
public soft (value: HexString | number | string | bigint | BN | Uint8Array): DeriveJunction {
|
||||
public soft (value: number | string | bigint | BN | Uint8Array): DeriveJunction {
|
||||
if (isNumber(value) || isBn(value) || isBigInt(value)) {
|
||||
return this.soft(bnToU8a(value, BN_LE_256_OPTS));
|
||||
} else if (isHex(value)) {
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
/// <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 => {
|
||||
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]));
|
||||
});
|
||||
|
||||
it('does not extract from invalid paths', (): void => {
|
||||
it('does not extract from invalid paths (1)', (): void => {
|
||||
expect(
|
||||
(): ExtractResult => keyExtractPath('1/2')
|
||||
).toThrow(/does not match input/);
|
||||
});
|
||||
|
||||
it('does not extract from invalid paths', (): void => {
|
||||
it('does not extract from invalid paths (2)', (): void => {
|
||||
expect(
|
||||
(): ExtractResult => keyExtractPath('hello')
|
||||
).toThrow(/does not match input/);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DeriveJunction } from './DeriveJunction.js';
|
||||
const RE_JUNCTION = /\/(\/?)([^/]+)/g;
|
||||
|
||||
export interface ExtractResult {
|
||||
parts: null | string[];
|
||||
parts: string[] | null;
|
||||
path: DeriveJunction[];
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
/// <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 => {
|
||||
it('does not extract from invalid suri', (): void => {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { DeriveJunction } from './DeriveJunction.js';
|
||||
import type { DeriveJunction } from './DeriveJunction.js';
|
||||
|
||||
import { keyExtractPath } from './extractPath.js';
|
||||
|
||||
export interface ExtractResult {
|
||||
@@ -24,7 +25,7 @@ export function keyExtractSuri (suri: string): ExtractResult {
|
||||
throw new Error('Unable to match provided value to a secret URI');
|
||||
}
|
||||
|
||||
const [, phrase, , derivePath, , , password] = matches as string[];
|
||||
const [, phrase, , derivePath, , , password] = matches;
|
||||
const { path } = keyExtractPath(derivePath);
|
||||
|
||||
return {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Keypair, KeypairType } from '../types.js';
|
||||
import type { DeriveJunction } from './DeriveJunction.js';
|
||||
|
||||
import { DeriveJunction } from './DeriveJunction.js';
|
||||
import { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
||||
import { keyHdkdEd25519 } from './hdkdEd25519.js';
|
||||
import { keyHdkdSr25519 } from './hdkdSr25519.js';
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Keypair } from '../types.js';
|
||||
|
||||
import { DeriveJunction } from './DeriveJunction.js';
|
||||
import type { DeriveJunction } from './DeriveJunction.js';
|
||||
|
||||
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 => {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Keypair } from '../types.js';
|
||||
import type { DeriveJunction } from './DeriveJunction.js';
|
||||
|
||||
import { sr25519DeriveHard } from '../sr25519/deriveHard.js';
|
||||
import { sr25519DeriveSoft } from '../sr25519/deriveSoft.js';
|
||||
import { DeriveJunction } from './DeriveJunction.js';
|
||||
|
||||
export function keyHdkdSr25519 (keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair {
|
||||
return isSoft
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
export { keyExtractPath } from './extractPath.js';
|
||||
export { keyExtractSuri } from './extractSuri.js';
|
||||
export { keyFromPath } from './fromPath.js';
|
||||
export { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
||||
export { keyHdkdEd25519 } from './hdkdEd25519.js';
|
||||
export { keyHdkdSr25519 } from './hdkdSr25519.js';
|
||||
export { keyHdkdEcdsa } from './hdkdEcdsa.js';
|
||||
|
||||
@@ -3,25 +3,78 @@
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { entropyToMnemonic, mnemonicToEntropy } from './bip39.js';
|
||||
import DEFAULT_WORDLIST from './bip39-en.js';
|
||||
import * as lists from './wordlists/index.js';
|
||||
import { entropyToMnemonic, generateMnemonic, mnemonicToEntropy, validateMnemonic } from './bip39.js';
|
||||
|
||||
describe('wordlist', (): void => {
|
||||
it('has the correct number of words', (): void => {
|
||||
expect(DEFAULT_WORDLIST).toHaveLength(2048);
|
||||
});
|
||||
describe('wordlists', (): void => {
|
||||
for (const [lang, words] of Object.entries(lists)) {
|
||||
describe(`language ${lang}`, (): void => {
|
||||
it('has the correct number of words', (): void => {
|
||||
expect(words).toHaveLength(2048);
|
||||
});
|
||||
|
||||
it('has no empty words', (): void => {
|
||||
expect(DEFAULT_WORDLIST.some((n) => !n.length || n.trim() !== n)).toEqual(false);
|
||||
});
|
||||
it('has no empty words', (): void => {
|
||||
expect(
|
||||
words.some((w) => !w.length || w.trim() !== w)
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
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(
|
||||
entropyToMnemonic(mnemonicToEntropy(m))
|
||||
entropyToMnemonic(mnemonicToEntropy(entropyToMnemonic(e)))
|
||||
).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 { randomAsU8a } from '../random/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_ENTROPY = 'Invalid entropy';
|
||||
const INVALID_CHECKSUM = 'Invalid mnemonic checksum';
|
||||
|
||||
/** @internal */
|
||||
function normalize (str?: string): string {
|
||||
return (str || '').normalize('NFKD');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function binaryToByte (bin: string): number {
|
||||
return parseInt(bin, 2);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function bytesToBinary (bytes: number[]): string {
|
||||
return bytes.map((x) => x.toString(2).padStart(8, '0')).join('');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function deriveChecksumBits (entropyBuffer: Uint8Array): string {
|
||||
return bytesToBinary(
|
||||
Array.from(sha256AsU8a(entropyBuffer))
|
||||
@@ -50,7 +54,7 @@ export function mnemonicToSeedSync (mnemonic: string, password?: string): Uint8A
|
||||
).password;
|
||||
}
|
||||
|
||||
export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
||||
export function mnemonicToEntropy (mnemonic: string, wordlist: string[] = DEFAULT_WORDLIST): Uint8Array {
|
||||
const words = normalize(mnemonic).split(' ');
|
||||
|
||||
if (words.length % 3 !== 0) {
|
||||
@@ -60,7 +64,7 @@ export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
||||
// convert word indices to 11 bit binary strings
|
||||
const bits = words
|
||||
.map((word): string => {
|
||||
const index = DEFAULT_WORDLIST.indexOf(word);
|
||||
const index = wordlist.indexOf(word);
|
||||
|
||||
if (index === -1) {
|
||||
throw new Error(INVALID_MNEMONIC);
|
||||
@@ -77,7 +81,7 @@ export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
||||
|
||||
// calculate the checksum and compare
|
||||
const matched = entropyBits.match(/(.{1,8})/g);
|
||||
const entropyBytes = matched && matched.map(binaryToByte);
|
||||
const entropyBytes = matched?.map(binaryToByte);
|
||||
|
||||
if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) {
|
||||
throw new Error(INVALID_ENTROPY);
|
||||
@@ -92,14 +96,14 @@ export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
||||
return entropy;
|
||||
}
|
||||
|
||||
export function entropyToMnemonic (entropy: Uint8Array): string {
|
||||
export function entropyToMnemonic (entropy: Uint8Array, wordlist: string[] = DEFAULT_WORDLIST): string {
|
||||
// 128 <= ENT <= 256
|
||||
if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) {
|
||||
throw new Error(INVALID_ENTROPY);
|
||||
}
|
||||
|
||||
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?.map((b) => wordlist[binaryToByte(b)]);
|
||||
|
||||
if (!mapped || (mapped.length < 12)) {
|
||||
throw new Error('Unable to map entropy to mnemonic');
|
||||
@@ -108,13 +112,13 @@ export function entropyToMnemonic (entropy: Uint8Array): string {
|
||||
return mapped.join(' ');
|
||||
}
|
||||
|
||||
export function generateMnemonic (numWords: 12 | 15 | 18 | 21 | 24): string {
|
||||
return entropyToMnemonic(randomAsU8a((numWords / 3) * 4));
|
||||
export function generateMnemonic (numWords: 12 | 15 | 18 | 21 | 24, wordlist?: string[]): string {
|
||||
return entropyToMnemonic(randomAsU8a((numWords / 3) * 4), wordlist);
|
||||
}
|
||||
|
||||
export function validateMnemonic (mnemonic: string): boolean {
|
||||
export function validateMnemonic (mnemonic: string, wordlist?: string[]): boolean {
|
||||
try {
|
||||
mnemonicToEntropy(mnemonic);
|
||||
mnemonicToEntropy(mnemonic, wordlist);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { cryptoWaitReady } from '../index.js';
|
||||
import { french as frenchWords } from './wordlists/index.js';
|
||||
import { mnemonicGenerate } from './generate.js';
|
||||
import { mnemonicValidate } from './validate.js';
|
||||
|
||||
@@ -16,11 +17,27 @@ describe('mnemonicGenerate', (): void => {
|
||||
).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]) {
|
||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||
for (const num of [12, 15, 18, 21, 24] as const) {
|
||||
it(`generates a valid mnemonic (${num} words)`, (): void => {
|
||||
const mnemonic = mnemonicGenerate(num, onlyJs);
|
||||
const mnemonic = mnemonicGenerate(num, undefined, onlyJs);
|
||||
const isValid = mnemonicValidate(mnemonic);
|
||||
|
||||
expect(mnemonic.split(' ')).toHaveLength(num);
|
||||
@@ -29,8 +46,8 @@ describe('mnemonicGenerate', (): void => {
|
||||
}
|
||||
|
||||
it('generates non-deterministic', (): void => {
|
||||
const m1 = mnemonicGenerate(24, onlyJs);
|
||||
const m2 = mnemonicGenerate(24, onlyJs);
|
||||
const m1 = mnemonicGenerate(24, undefined, onlyJs);
|
||||
const m2 = mnemonicGenerate(24, undefined, onlyJs);
|
||||
|
||||
expect(m1 === m2).toEqual(false);
|
||||
expect(mnemonicValidate(m1)).toEqual(true);
|
||||
|
||||
@@ -18,8 +18,8 @@ import { generateMnemonic } from './bip39.js';
|
||||
* const mnemonic = mnemonicGenerate(); // => string
|
||||
* ```
|
||||
*/
|
||||
export function mnemonicGenerate (numWords: 12 | 15 | 18 | 21 | 24 = 12, onlyJs?: boolean): string {
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
export function mnemonicGenerate (numWords: 12 | 15 | 18 | 21 | 24 = 12, wordlist?: string[], onlyJs?: boolean): string {
|
||||
return !hasBigInt || (!wordlist && !onlyJs && isReady())
|
||||
? bip39Generate(numWords)
|
||||
: generateMnemonic(numWords);
|
||||
: generateMnemonic(numWords, wordlist);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { cryptoWaitReady } from '../index.js';
|
||||
import tests from '../sr25519/pair/testing.spec.js';
|
||||
import { french as frenchWords } from './wordlists/index.js';
|
||||
import { mnemonicToEntropy } from './toEntropy.js';
|
||||
|
||||
await cryptoWaitReady();
|
||||
@@ -16,9 +17,20 @@ describe('mnemonicToEntropy', (): void => {
|
||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||
tests.forEach(([mnemonic, entropy], 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';
|
||||
|
||||
export function mnemonicToEntropy (mnemonic: string, onlyJs?: boolean): Uint8Array {
|
||||
return !hasBigInt || (!onlyJs && isReady())
|
||||
export function mnemonicToEntropy (mnemonic: string, wordlist?: string[], onlyJs?: boolean): Uint8Array {
|
||||
return !hasBigInt || (!wordlist && !onlyJs && isReady())
|
||||
? bip39ToEntropy(mnemonic)
|
||||
: jsToEntropy(mnemonic);
|
||||
: jsToEntropy(mnemonic, wordlist);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { u8aEq, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { cryptoWaitReady } from '../index.js';
|
||||
import tests from '../sr25519/pair/testing.spec.js';
|
||||
import { korean as koreanWords } from './wordlists/index.js';
|
||||
import { mnemonicToMiniSecret } from './toMiniSecret.js';
|
||||
|
||||
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 => {
|
||||
expect(
|
||||
u8aEq(
|
||||
mnemonicToMiniSecret(MNEMONIC, password, true),
|
||||
mnemonicToMiniSecret(MNEMONIC, password, false)
|
||||
mnemonicToMiniSecret(MNEMONIC, password, undefined, true),
|
||||
mnemonicToMiniSecret(MNEMONIC, password, undefined, false)
|
||||
)
|
||||
).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]) {
|
||||
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
||||
it('generates a valid seed', (): void => {
|
||||
expect(
|
||||
u8aToHex(mnemonicToMiniSecret(MNEMONIC, undefined, onlyJs))
|
||||
u8aToHex(mnemonicToMiniSecret(MNEMONIC, undefined, undefined, onlyJs))
|
||||
).toEqual(SEED);
|
||||
});
|
||||
|
||||
it('fails with non-mnemonics', (): void => {
|
||||
expect(
|
||||
() => mnemonicToMiniSecret('foo bar baz', undefined, onlyJs)
|
||||
() => mnemonicToMiniSecret('foo bar baz', undefined, undefined, onlyJs)
|
||||
).toThrow(/mnemonic specified/);
|
||||
});
|
||||
|
||||
tests.forEach(([mnemonic, , seed], index): void => {
|
||||
it(`Created correct seed for ${index}`, (): void => {
|
||||
expect(
|
||||
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate', onlyJs))
|
||||
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate', undefined, onlyJs))
|
||||
).toEqual(
|
||||
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
|
||||
seed.substring(0, 66)
|
||||
|
||||
@@ -8,16 +8,14 @@ import { pbkdf2Encode } from '../pbkdf2/index.js';
|
||||
import { mnemonicToEntropy } from './toEntropy.js';
|
||||
import { mnemonicValidate } from './validate.js';
|
||||
|
||||
export function mnemonicToMiniSecret (mnemonic: string, password = '', onlyJs?: boolean): Uint8Array {
|
||||
if (!mnemonicValidate(mnemonic)) {
|
||||
export function mnemonicToMiniSecret (mnemonic: string, password = '', wordlist?: string[], onlyJs?: boolean): Uint8Array {
|
||||
if (!mnemonicValidate(mnemonic, wordlist, onlyJs)) {
|
||||
throw new Error('Invalid bip39 mnemonic specified');
|
||||
}
|
||||
|
||||
if (!onlyJs && isReady()) {
|
||||
} else if (!wordlist && !onlyJs && isReady()) {
|
||||
return bip39ToMiniSecret(mnemonic, password);
|
||||
}
|
||||
|
||||
const entropy = mnemonicToEntropy(mnemonic);
|
||||
const entropy = mnemonicToEntropy(mnemonic, wordlist);
|
||||
const salt = stringToU8a(`mnemonic${password}`);
|
||||
|
||||
// return the first 32 bytes as the seed
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user