Compare commits

...
108 Commits
Author SHA1 Message Date
github-actions[bot] 1fdc2c8dae [CI Skip] release/stable 12.2.2
skip-checks: true
2023-06-04 09:06:26 +00:00
Jaco b6a2693e5f 12.2.2 (#1839) 2023-06-04 11:58:18 +03:00
github-actions[bot] 8b3687e062 [CI Skip] bump/beta 12.2.2-7-x
skip-checks: true
2023-06-04 08:30:55 +00:00
Jaco 3a8429b687 Bump noble/{curves, hashes} (#1838) 2023-06-04 11:24:40 +03:00
github-actions[bot] 26e9b01198 [CI Skip] bump/beta 12.2.2-6-x
skip-checks: true
2023-06-02 10:51:44 +00:00
Jaco 76d71d946d Bump deps (w/ TS 5.1) (#1837)
* Bump deps (w/ TS 5.1)

* Adjust fallback

* Revert promisify adjustments
2023-06-02 13:44:54 +03:00
github-actions[bot] 0ebc7bd374 [CI Skip] bump/beta 12.2.2-5-x
skip-checks: true
2023-05-30 08:57:58 +00:00
Jaco d94c126744 Apply missing count assignment in for loops (#1836) 2023-05-30 11:50:04 +03:00
github-actions[bot] 86597dcb17 [CI Skip] bump/beta 12.2.2-4-x
skip-checks: true
2023-05-28 07:53:44 +00:00
Jaco 1be682827b Bump deps (incl Ledger) (#1835) 2023-05-28 10:47:42 +03:00
github-actions[bot] 081b6b4f2b [CI Skip] bump/beta 12.2.2-3-x
skip-checks: true
2023-05-25 07:37:17 +00:00
Jaco 7dc38e78cf jg-bump-deps (#1834) 2023-05-25 10:29:17 +03:00
github-actions[bot] dcf214f250 [CI Skip] bump/beta 12.2.2-2-x
skip-checks: true
2023-05-21 09:48:48 +00:00
Jaco 2e82528e1b Bump dev (w/ eslint config adj) (#1832) 2023-05-21 12:42:39 +03:00
github-actions[bot] 090b91910f [CI Skip] bump/beta 12.2.2-1-x
skip-checks: true
2023-05-18 09:05:38 +00:00
Jaco 058d197646 Adjust tsconfig usage (w/ latest dev) (#1831) 2023-05-18 11:59:17 +03:00
github-actions[bot] 0fca8904e6 [CI Skip] bump/beta 12.2.2-0-x
skip-checks: true
2023-05-18 05:35:04 +00:00
Jaco 0bf7bc416a Bump dev deps (#1830) 2023-05-18 08:29:07 +03:00
github-actions[bot] ea08763307 [CI Skip] release/stable 12.2.1
skip-checks: true
2023-05-13 08:25:36 +00:00
Jaco 5272645abe 12.2.1 (#1829) 2023-05-13 11:17:53 +03:00
Jaco e5373c35c8 Unroll u8aToBigInt loops (#1821)
* Unroll u8aToBigInt loops

* Bump dev

* Rolling tests
2023-05-13 10:51:46 +03:00
github-actions[bot] b73b96e412 [CI Skip] bump/beta 12.1.3-2-x
skip-checks: true
2023-05-06 09:00:28 +00:00
Jaco 18d24bf509 Bump dev (#1827) 2023-05-06 11:52:33 +03:00
github-actions[bot] fe230f143f [CI Skip] bump/beta 12.1.3-1-x
skip-checks: true
2023-05-05 07:07:53 +00:00
Jaco 6357c1e040 Update Constructor interface params (#1823)
* Update Constructor interface params

* Adjust

* Adjust
2023-05-05 10:01:56 +03:00
github-actions[bot] 1876efe13e [CI Skip] bump/beta 12.1.3-0-x
skip-checks: true
2023-05-05 06:46:01 +00:00
Jaco 9de142b5f6 Bump deps (#1826) 2023-05-05 09:39:58 +03:00
github-actions[bot] e5cb0ba2b4 [CI Skip] release/stable 12.1.2
skip-checks: true
2023-05-01 16:14:41 +00:00
Jaco dba5d3e7b3 Fix typings for isChildClass (#1824)
* Fix typings for isChildClass

* Adjust
2023-05-01 19:08:41 +03:00
github-actions[bot] 8ccfecfff8 [CI Skip] bump/beta 12.1.2-0-x
skip-checks: true
2023-04-29 10:42:54 +00:00
Jaco f2e79ffe67 Align u8aToBigInt tests with u8aToBn (#1820)
* Align u8aToBigInt tests with u8aToBn

* Remove unused import
2023-04-29 13:33:53 +03:00
github-actions[bot] e7f595a11f [CI Skip] release/stable 12.1.1
skip-checks: true
2023-04-29 05:50:45 +00:00
Jaco 770471aef0 12.1.1 (#1819) 2023-04-29 08:44:25 +03:00
github-actions[bot] 6b1ff0036e [CI Skip] bump/beta 12.0.2-2-x
skip-checks: true
2023-04-28 06:13:30 +00:00
Jaco fee81b89ac Bump deps (#1818) 2023-04-28 09:07:41 +03:00
github-actions[bot] c4d5b8e1ae [CI Skip] bump/beta 12.0.2-1-x
skip-checks: true
2023-04-26 09:36:39 +00:00
Jaco 5674b1df67 Bump deps w/ export ordering (#1817) 2023-04-26 12:29:21 +03:00
github-actions[bot] 5ccb3e85f8 [CI Skip] bump/beta 12.0.2-0-x
skip-checks: true
2023-04-24 04:59:26 +00:00
Jaco 785a23433d Flatten Buffer | Uint8Array types (#1816)
* Flatten Buffer | Uint8Array types

* Remove dangling Buffer references

* CHANGELOG

* Adjust
2023-04-24 07:53:31 +03:00
github-actions[bot] bead42ca5f [CI Skip] release/stable 12.0.1
skip-checks: true
2023-04-22 07:44:07 +00:00
Jaco 2d2a1a5989 12.0.1 (#1815)
* 12.0.1

* Inline xxhash single-use

* Adjust comments
2023-04-22 10:37:53 +03:00
github-actions[bot] db4dde0a57 [CI Skip] bump/beta 11.1.4-19-x
skip-checks: true
2023-04-21 08:23:53 +00:00
Jaco b5d83f8836 Allow wordlist? param to mnemonic* functions (#1814) 2023-04-21 11:16:43 +03:00
github-actions[bot] cdf6cc6096 [CI Skip] bump/beta 11.1.4-18-x
skip-checks: true
2023-04-21 07:34:55 +00:00
Jaco dfd07e04d4 Align x-randomvalues with webCrypto (#1782)
* Align x-randomvalues with webCrypto

* Deno export from browser

* export * for x-ws

* export * from RN

* CHANGELOG
2023-04-21 10:27:30 +03:00
github-actions[bot] f5a3a6fd73 [CI Skip] bump/beta 11.1.4-17-x
skip-checks: true
2023-04-21 07:18:16 +00:00
Jaco 51a7263d38 Bump dev (w/ Node 16+ only) (#1813)
* Bump dev (w/ Node 16+ only)

* Lint

* Fix build
2023-04-21 10:10:27 +03:00
github-actions[bot] e3b11360ab [CI Skip] bump/beta 11.1.4-16-x
skip-checks: true
2023-04-20 06:58:05 +00:00
Jaco b4bed3d801 Bump deps (#1812) 2023-04-20 09:52:10 +03:00
github-actions[bot] 1f8b573d81 [CI Skip] bump/beta 11.1.4-15-x
skip-checks: true
2023-04-15 11:37:12 +00:00
Jaco a0e5d48208 CHANGELOG (#1811) 2023-04-15 14:30:49 +03:00
github-actions[bot] 6ce32b8039 [CI Skip] bump/beta 11.1.4-14-x
skip-checks: true
2023-04-15 11:15:05 +00:00
Jaco 3ee810904e Adjust isCodec with better API alignment (#1810)
* Adjust isCodec with better API alignment

* Adjust tests

* Remove test dupes
2023-04-15 14:07:44 +03:00
github-actions[bot] ed73a7912b [CI Skip] bump/beta 11.1.4-13-x
skip-checks: true
2023-04-14 07:28:50 +00:00
Jaco 4ec2cf9e43 Small adjustment to x-* exports (#1809) 2023-04-14 10:22:53 +03:00
github-actions[bot] 38ac05203e [CI Skip] release/beta 11.1.4-12
skip-checks: true
2023-04-13 13:13:49 +00:00
Jaco bb6a2b4468 Add missing peerDependencies for x-randomvalues (#1808)
* Add missing peerDependencies for x-randomvalues

* publish
2023-04-13 16:07:34 +03:00
github-actions[bot] 3c9b20e902 [CI Skip] release/beta 11.1.4-11
skip-checks: true
2023-04-13 11:39:47 +00:00
Jaco e1a2ea49cb x-randomvalues w/ shared base64 decoding (#1807)
* x-randomvalues w/ shared base64 decoding

* Adjust

* npm publish
2023-04-13 14:33:45 +03:00
github-actions[bot] 892004563f [CI Skip] bump/beta 11.1.4-10-x
skip-checks: true
2023-04-13 06:20:56 +00:00
Jaco efe4ce8d9d Allow for wordlists in JS bip39 functions (#1805) 2023-04-13 09:14:45 +03:00
github-actions[bot] f0f561e243 [CI Skip] bump/beta 11.1.4-9-x
skip-checks: true
2023-04-12 19:52:44 +00:00
Shamilkhan 56e34586b3 Add genesis hash for Cere Network (#1806)
* Add genesis hash for Cere Network

* Put Cere Network in correct alphabet order

* Rename CereNetwork to Cere
2023-04-12 22:46:39 +03:00
github-actions[bot] 667fe8fb17 [CI Skip] bump/beta 11.1.4-8-x
skip-checks: true
2023-04-12 11:09:35 +00:00
Jaco 3fd8074877 Add missing bip39 wordlists (only en is used) (#1803) 2023-04-12 14:01:27 +03:00
github-actions[bot] 91a2eac220 [CI Skip] release/beta 11.1.4-7
skip-checks: true
2023-04-12 10:04:21 +00:00
Jaco 455ae2ccde Use @noble/curves (secp256k1 + ed25519) (#1776)
* Use @noble/curves (secp256k1 only for now)

* Re-add canonical signatures (now lowS)

* Swap tweetnacl usage for ed25519

* Adjust previously failing tests

* Adjust test for ethereum encoding

* hasBigInt for ed25519 operations

* CHANGELOG

* Publich beta to npm for size check
2023-04-12 12:58:17 +03:00
github-actions[bot] 9d43b787fd [CI Skip] bump/beta 11.1.4-6-x
skip-checks: true
2023-04-12 09:45:36 +00:00
Jaco 29551e46b0 Import box functionality from tweetnacl (#1785)
* Import box functionality from tweetnacl

* Remove box/boxOpen functionality

* Additional comment

* Import secretbox test vectors

* Allow empty base64 input

* Combine non-xor crypto_stream usage with xor

* Adjust

* inline let

* Rename tests, extract test vectors

* Adjust chnages comments

* Remove box keypair

* Remove rng set operation

* Inline adjust

* Verify adjustment
2023-04-12 12:39:31 +03:00
Jaco 103745f845 Trace tweetnacl usage (Step 5: secretbox & .open available) (#1802) 2023-04-12 12:25:41 +03:00
Jaco cd7a32cf1f Trace tweetnacl usage (step 4: apply TS types) (#1801) 2023-04-12 12:11:40 +03:00
Jaco 5004d1d79f Trace tweetnacl usage (step 3: comment all code) (#1800) 2023-04-12 11:42:15 +03:00
Jaco 2607203925 Trace tweetnacl usage (step 2: move to TS) (#1799) 2023-04-12 11:39:17 +03:00
Jaco 5abab5bf13 Trace tweetnacl usage (step 1: raw initial import) (#1798) 2023-04-12 11:35:50 +03:00
github-actions[bot] a990b4e40f [CI Skip] bump/beta 11.1.4-5-x
skip-checks: true
2023-04-12 08:14:47 +00:00
Jaco 997f8f6a51 Align x-bigint extraction with other x-* (#1797) 2023-04-12 11:08:48 +03:00
github-actions[bot] 23e055869c [CI Skip] bump/beta 11.1.4-4-x
skip-checks: true
2023-04-11 12:00:36 +00:00
Jaco de85d063a4 Bump dev (w/ lint updates) (#1795)
* Bump dev (w/ lint updates)

* Bump dev

* Adjust behavior for global setting

* Adjust versionDetect expectations
2023-04-11 14:52:49 +03:00
github-actions[bot] 5964f790b5 [CI Skip] bump/beta 11.1.4-3-x
skip-checks: true
2023-04-10 07:27:42 +00:00
Jaco a767ef68ca Bump dev (w/ eslint adjustments) (#1794) 2023-04-10 10:21:33 +03:00
github-actions[bot] c096a4981d [CI Skip] bump/beta 11.1.4-2-x
skip-checks: true
2023-04-08 08:09:52 +00:00
Jaco 7dcdef17c3 Bump TypeScript (#1793)
* Bump TypeScript

* Bump dev

* Bump dev, no npm:
2023-04-08 11:02:20 +03:00
github-actions[bot] ef839a7a42 [CI Skip] bump/beta 11.1.4-1-x
skip-checks: true
2023-04-04 05:40:36 +00:00
Jaco 7bf1706994 Update lock wf (#1791) 2023-04-04 08:31:58 +03:00
github-actions[bot] 2999987fb0 [CI Skip] bump/beta 11.1.4-0-x
skip-checks: true
2023-04-02 07:01:09 +00:00
Jaco 6ba45086b5 Move type-only imports (w/ verbatimModuleSyntax) (#1790) 2023-04-02 09:53:43 +03:00
github-actions[bot] e3c51d4b6b [CI Skip] release/stable 11.1.3
skip-checks: true
2023-04-01 07:04:11 +00:00
Jaco 1295c85df3 11.1.3 (#1789) 2023-04-01 09:58:20 +03:00
github-actions[bot] 14d66c32de [CI Skip] bump/beta 11.1.3-4-x
skip-checks: true
2023-03-31 06:24:39 +00:00
Jaco b794d22ac4 Allow empty string as valid base32/base58/base64 decoder input (#1788)
* Allow empty string as valid base32/base58/base64 decoder input

* Remove empty failure

* Validation with optional validation flag

* Empty validation
2023-03-31 09:18:38 +03:00
github-actions[bot] edb62407e2 [CI Skip] bump/beta 11.1.3-3-x
skip-checks: true
2023-03-31 05:14:41 +00:00
Jaco 45b040fbf8 Additional __PURE__ annotations (#1787)
* Additional __PURE__ annotations

* Revert as const (This _could_ yield breaking external changes)
2023-03-31 08:08:01 +03:00
github-actions[bot] 777b823317 [CI Skip] bump/beta 11.1.3-2-x
skip-checks: true
2023-03-29 04:28:57 +00:00
Cameron Fairchild c5ef717398 Add bittensor details (#1783)
* add with todo

* update genesis hash

* remove from ledger

* remove from ledger
2023-03-29 07:21:56 +03:00
github-actions[bot] 98f0933da5 [CI Skip] bump/beta 11.1.3-1-x
skip-checks: true
2023-03-25 15:52:28 +00:00
Jaco 493d0df0c1 Add repo dev req. for Node.js (#1779) 2023-03-25 17:46:33 +02:00
github-actions[bot] 5d8e92f17c [CI Skip] bump/beta 11.1.3-0-x
skip-checks: true
2023-03-25 10:57:53 +00:00
Jaco 2ce178cad2 Bump dev (w/ some node:test adjustments) (#1778) 2023-03-25 12:51:53 +02:00
github-actions[bot] 9ccac88372 [CI Skip] release/stable 11.1.2
skip-checks: true
2023-03-25 07:20:00 +00:00
Jaco 0aa441de96 11.1.2 (#1777)
* 11.1.2

* Bump dev

* Bump deps
2023-03-25 09:14:10 +02:00
github-actions[bot] 78941a3cde [CI Skip] bump/beta 11.1.2-3-x
skip-checks: true
2023-03-24 08:37:26 +00:00
Jaco 514570a5fb Additional hw-ledger cleanups (#1775)
* Additional hw-ledger cleanups

* Rename ledgerName
2023-03-24 10:29:45 +02:00
github-actions[bot] ad2da94408 [CI Skip] bump/beta 11.1.2-2-x
skip-checks: true
2023-03-24 08:14:57 +00:00
Jaco 803edbb8cc Small Ledger process dedupe (#1774)
* Small Ledger process dedupe

* Add yarn.lock
2023-03-24 10:08:45 +02:00
github-actions[bot] 94692cbbb4 [CI Skip] bump/beta 11.1.2-1-x
skip-checks: true
2023-03-24 07:43:44 +00:00
Jaco 0a27c23439 Specific per-method JSDoc for hw-ledger (#1773)
* Specific per-method JSDoc for hw-ledger

* Adjust, less types floating around
2023-03-24 09:36:42 +02:00
github-actions[bot] 0a1cfb15ef [CI Skip] bump/beta 11.1.2-0-x
skip-checks: true
2023-03-23 09:17:47 +00:00
Jaco cd494d7de0 Expand error details on invalid publicKey (#1772) 2023-03-23 11:11:53 +02:00
255 changed files with 8603 additions and 2123 deletions
-2
View File
@@ -1,2 +0,0 @@
packages/x-noble-hashes/**/*.ts
packages/x-noble-secp256k1/**/*.ts
-22
View File
@@ -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'
}
};
+4 -4
View File
@@ -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.
+1 -1
View File
@@ -22,5 +22,5 @@ jobs:
- name: ${{ matrix.step }}
if: always()
run: |
yarn install --immutable | grep -v 'YN0013'
yarn install --immutable
yarn ${{ matrix.step }}
+1 -1
View File
@@ -27,5 +27,5 @@ jobs:
node-version: 'lts/*'
- name: ${{ matrix.step }}
run: |
yarn install --immutable | grep -v 'YN0013'
yarn install --immutable
yarn ${{ matrix.step }}
+5
View File
@@ -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:
+78
View File
@@ -1,5 +1,83 @@
# CHANGELOG
## 12.2.2 Jun 4, 2023
Changes:
- Apply missing count assignment for `for (...)` loops
- Remove unused `@types/*` dev dependencies
- Upgrade dependencies to latest stable versions
## 12.2.1 May 13, 2023
Changes:
- Align `u8aToBigInt` tests with `u8aToBn`
- Unroll loops on most-frequently used paths for `u8aToBigInt`
- Add `module` to `package.json` export map (ESM-only)
- Upgrade dependencies to latest stable versions
## 12.1.2 May 1, 2023
Changes:
- Adjust typing for `isChildClass` & `Constructor` usage
## 12.1.1 Apr 29, 2023
Changes:
- Add shareable `identity` & `noop` functions
- Flatten `Buffer | Uint8Array` types (as used) to base-only `Uint8Array`
- Apply `readonly` specifiers to private class fields where applicable
- Adjust compilation output for `__internal__` class fields
- Remove unused types from `util`
- Upgrade dependencies to latest stable versions
## 12.0.1 Apr 22, 2023
Contributed:
- Add Cere genesisHash (Thanks to https://github.com/shamilkhan)
Changes:
- Swap secp256k1 functionality to `@noble/curves`
- Swap ed25519 functionality to `@noble/curves`
- Replace `tweetnacl` secretbox usage with slimmer local version
- Adjust `isCodec` helper with closer API alignment
- Initial steps to multi-language bip39 support
- Use Node webcrypto for Node `getRandomValues` support
- Upgrade dependencies to latest stable versions
- Drop support for Node 14 (EOL 30 Apr 2023)
## 11.1.3 Apr 1, 2023
Contributed:
- Add Bittensor genesisHash (Thanks to https://github.com/camfairchild)
Changes:
- Allow empty string as valid base32/base58/base64 decoder input
- Add additional/missing `/*#__PURE__*/` annotations
- Upgrade dependencies to latest stable versions
## 11.1.2 Mar 25, 2023
Changes:
- Expand error details for invalid publicKeys in secp256k1 compress/expand operations
- Expand `@polkadot/hw-ledger` with specific per-method JSDoc
- Upgrade dependencies to latest stable versions
## 11.1.1 Mar 18, 2023
Contributed:
+3 -1
View File
@@ -1,4 +1,4 @@
1567 Jaco 11.1.1 (#1771)
1622 Jaco 12.2.2 (#1839)
12 Carlo Sala feat(networks): support ledger for pendulum (#1739)
9 Antoine Estienne Add eth uri keyring test (#1291)
6 Amaury Martiny Add tests from Rust (#283)
@@ -23,6 +23,7 @@
1 amphineko chore: fix typo in versionDetect messages (#941)
1 Axel Chalon Simplify @polkadot/keyring KeyringPair (#419)
1 Brad Larson [FIX] Adjust error message (#646)
1 Cameron Fairchild Add bittensor details (#1783)
1 Carlos Medeiros add hydradx to knownLedger (#1647)
1 Eliott Teissonniere add nodle ledger specs (#1089)
1 Guilane DENGUIR feat(VTB): Added support for VTB blockchain (#1651)
@@ -47,6 +48,7 @@
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)
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2017-2023 @polkadot/dev authors & contributors
// SPDX-License-Identifier: Apache-2.0
import baseConfig from '@polkadot/dev/config/eslint';
export default [
...baseConfig
];
+7 -7
View File
@@ -2,7 +2,7 @@
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/polkadot-js/common/issues",
"engines": {
"node": ">=14"
"node": ">=18.14"
},
"homepage": "https://github.com/polkadot-js/common#readme",
"license": "Apache-2.0",
@@ -14,10 +14,10 @@
},
"sideEffects": false,
"type": "module",
"version": "11.1.1",
"version": "12.2.2",
"versions": {
"git": "11.1.1",
"npm": "11.1.1"
"git": "12.2.2",
"npm": "12.2.2"
},
"workspaces": [
"packages/*"
@@ -37,10 +37,10 @@
"test:one": "polkadot-dev-run-test --env browser"
},
"devDependencies": {
"@polkadot/dev": "^0.72.15",
"@types/node": "^18.15.3"
"@polkadot/dev": "^0.75.16",
"@types/node": "^20.2.5"
},
"resolutions": {
"typescript": "^5.0.2"
"typescript": "^5.1.3"
}
}
+8 -8
View File
@@ -2,7 +2,7 @@
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/polkadot-js/common/issues",
"engines": {
"node": ">=14"
"node": ">=16"
},
"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.1",
"version": "12.2.2",
"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.1",
"tslib": "^2.5.0"
"@ledgerhq/hw-transport": "^6.28.4",
"@ledgerhq/hw-transport-webhid": "^6.27.15",
"@ledgerhq/hw-transport-webusb": "^6.27.15",
"@polkadot/util": "12.2.2",
"tslib": "^2.5.3"
},
"optionalDependencies": {
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.9"
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.12"
}
}
+4 -16
View File
@@ -1,23 +1,11 @@
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Transport, TransportDef } from './types.js';
import LedgerHid from '@ledgerhq/hw-transport-webhid';
import LedgerUsb from '@ledgerhq/hw-transport-webusb';
import LedgerWebHid from '@ledgerhq/hw-transport-webhid';
import LedgerWebUsb from '@ledgerhq/hw-transport-webusb';
import { createDefs } from './util.js';
export { packageInfo } from './packageInfo.js';
// See usage of Transport interface in types.ts
export const transports: TransportDef[] = [
{
create: (): Promise<Transport> =>
(LedgerWebUsb as unknown as Transport).create(),
type: 'webusb'
},
{
create: (): Promise<Transport> =>
(LedgerWebHid as unknown as Transport).create(),
type: 'hid'
}
];
export const transports = /*#__PURE__*/ createDefs(['webusb', LedgerUsb], ['hid', LedgerHid]);
+2 -2
View File
@@ -1,8 +1,8 @@
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TransportDef } from './types.js';
import { createDefs } from './util.js';
export { packageInfo } from './packageInfo.js';
export const transports: TransportDef[] = [];
export const transports = /*#__PURE__*/ createDefs();
+3 -10
View File
@@ -1,17 +1,10 @@
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Transport, TransportDef } from './types.js';
import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton';
import { createDefs } from './util.js';
export { packageInfo } from './packageInfo.js';
// See usage of Transport interface in types.ts
export const transports: TransportDef[] = [
{
create: (): Promise<Transport> =>
(LedgerHid as unknown as Transport).create(),
type: 'hid'
}
];
export const transports = /*#__PURE__*/ createDefs(['hid', LedgerHid]);
@@ -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.1' };
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '12.2.2' };
+7 -11
View File
@@ -1,21 +1,17 @@
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
// CJS, so we use import * syntax
import type * as HwTransport from '@ledgerhq/hw-transport';
// The actual namespaced Transport interface (as detailed on the next line)
//
// import type Transport from '@ledgerhq/hw-transport';
//
// does not quite work on moduleResolution: nodenext, so we just go with a
// very light interface here
export interface Transport {
create (): Promise<Transport>;
}
// u2f is deprecated an therefore not added
export type TransportType = 'hid' | 'webusb';
export type Transport = HwTransport.default;
export interface TransportDef {
/** Create a transport to be used in Ledger operations */
create (): Promise<Transport>;
/** The type of the underlying transport definition */
type: LedgerTypes;
type: TransportType;
}
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Transport, TransportDef, TransportType } from './types.js';
export function createDefs (...items: readonly [type: TransportType, Clazz: unknown][]): TransportDef[] {
return items.map(([type, Clazz]): TransportDef => ({
create: (): Promise<Transport> =>
(Clazz as Pick<TransportDef, 'create'>).create(),
type
}));
}
@@ -5,6 +5,9 @@
"outDir": "./build",
"rootDir": "./src"
},
"exclude": [
"**/mod.ts"
],
"references": [
{ "path": "../util/tsconfig.build.json" }
]
+6 -7
View File
@@ -2,7 +2,7 @@
"author": "Jaco Greeff <jacogr@gmail.com>",
"bugs": "https://github.com/polkadot-js/common/issues",
"engines": {
"node": ">=14"
"node": ">=16"
},
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger#readme",
"license": "Apache-2.0",
@@ -17,13 +17,12 @@
"./detectPackage.cjs"
],
"type": "module",
"version": "11.1.1",
"version": "12.2.2",
"main": "index.js",
"dependencies": {
"@ledgerhq/hw-transport": "^6.28.1",
"@polkadot/hw-ledger-transports": "11.1.1",
"@polkadot/util": "11.1.1",
"@zondax/ledger-substrate": "^0.40.5",
"tslib": "^2.5.0"
"@polkadot/hw-ledger-transports": "12.2.2",
"@polkadot/util": "12.2.2",
"@zondax/ledger-substrate": "^0.40.7",
"tslib": "^2.5.3"
}
}
+44 -33
View File
@@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
import type { SubstrateApp } from '@zondax/ledger-substrate';
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types.js';
import type { TransportDef, TransportType } from '@polkadot/hw-ledger-transports/types';
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js';
import { newSubstrateApp } from '@zondax/ledger-substrate';
@@ -29,28 +30,38 @@ 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)
/**
* @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;
#chain: Chain;
constructor (transport: TransportType, chain: Chain) {
const ledgerName = ledgerApps[chain];
const transportDef = transports.find(({ type }) => type === transport);
#transport: LedgerTypes;
constructor (transport: LedgerTypes, chain: Chain) {
// u2f is deprecated
if (!['hid', 'webusb'].includes(transport)) {
throw new Error(`Unsupported transport ${transport}`);
} else if (!Object.keys(ledgerApps).includes(chain)) {
throw new Error(`Unsupported chain ${chain}`);
if (!ledgerName) {
throw new Error(`Unsupported Ledger chain ${chain}`);
} else if (!transportDef) {
throw new Error(`Unsupported Ledger transport ${transport}`);
}
this.#chain = chain;
this.#transport = transport;
this.#ledgerName = ledgerName;
this.#transportDef = transportDef;
}
/**
* Returns the address associated with a specific account & address offset. Optionally
* asks for on-device confirmation
*/
public async getAddress (confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerAddress> {
return this.withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
@@ -62,6 +73,9 @@ export class Ledger {
});
}
/**
* Returns the version of the Ledger application on the device
*/
public async getVersion (): Promise<LedgerVersion> {
return this.withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion());
@@ -74,6 +88,9 @@ export class Ledger {
});
}
/**
* Signs a transaction on the Ledger device
*/
public async sign (message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerSignature> {
return this.withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
const buffer = u8aToBuffer(message);
@@ -85,27 +102,21 @@ export class Ledger {
});
}
async getApp (): Promise<SubstrateApp> {
if (!this.#app) {
const def = transports.find(({ type }) => type === this.#transport);
if (!def) {
throw new Error(`Unable to find a transport for ${this.#transport}`);
}
const transport = await def.create();
this.#app = newSubstrateApp(transport, ledgerApps[this.#chain]);
}
return this.#app;
}
/**
* @internal
*
* Returns a created SubstrateApp to perform operations against. Generally
* this is only used internally, to ensure consistent bahavior.
*/
async withApp <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> {
try {
const app = await this.getApp();
if (!this.#app) {
const transport = await this.#transportDef.create();
return await fn(app);
this.#app = newSubstrateApp(transport, this.#ledgerName);
}
return await fn(this.#app);
} catch (error) {
this.#app = null;
+1 -1
View File
@@ -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.1' };
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '12.2.2' };
-2
View File
@@ -3,8 +3,6 @@
import type { HexString } from '@polkadot/util/types';
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
export interface AccountOptions {
/** The index of the account */
account: number;
+4
View File
@@ -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" }
+16
View File
@@ -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" }
]
}
+7 -7
View File
@@ -3,7 +3,7 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"description": "Keyring management",
"engines": {
"node": ">=14"
"node": ">=16"
},
"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.1",
"version": "12.2.2",
"main": "index.js",
"dependencies": {
"@polkadot/util": "11.1.1",
"@polkadot/util-crypto": "11.1.1",
"tslib": "^2.5.0"
"@polkadot/util": "12.2.2",
"@polkadot/util-crypto": "12.2.2",
"tslib": "^2.5.3"
},
"peerDependencies": {
"@polkadot/util": "11.1.1",
"@polkadot/util-crypto": "11.1.1"
"@polkadot/util": "12.2.2",
"@polkadot/util-crypto": "12.2.2"
}
}
+6 -6
View File
@@ -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';
+2 -2
View File
@@ -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);
};
/**
+1 -1
View File
@@ -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.1' };
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '12.2.2' };
+1 -1
View File
@@ -3,6 +3,6 @@
export interface PairInfo {
publicKey: Uint8Array;
secretKey?: Uint8Array;
secretKey?: Uint8Array | undefined;
seed?: Uint8Array | null;
}
+1 -1
View File
@@ -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);
+13 -6
View File
@@ -47,7 +47,7 @@ describe('testingPairs', (): void => {
).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"
@@ -64,10 +64,17 @@ describe('testingPairs', (): void => {
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)
);
});
});
});
});
+4
View File
@@ -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" }
+18
View File
@@ -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" }
]
}
+6 -6
View File
@@ -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": ">=16"
},
"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.1",
"version": "12.2.2",
"main": "index.js",
"dependencies": {
"@polkadot/util": "11.1.1",
"@substrate/ss58-registry": "^1.39.0",
"tslib": "^2.5.0"
"@polkadot/util": "12.2.2",
"@substrate/ss58-registry": "^1.40.0",
"tslib": "^2.5.3"
},
"devDependencies": {
"@polkadot/hw-ledger": "11.1.1"
"@polkadot/hw-ledger": "12.2.2"
}
}
@@ -29,10 +29,16 @@ export const knownGenesis: KnownGenesis = {
'bifrost-kusama': [
'0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed'
],
bittensor: [
'0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03'
],
centrifuge: [
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
],
cere: [
'0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c'
],
composable: [
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
],
+3 -3
View File
@@ -13,8 +13,8 @@ describe('availableNetworks', (): void => {
expect(availableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]);
});
it.skip('has a sorted list (first external, last external)', (): void => {
expect(availableNetworks[3].displayName).toEqual('Acala');
it('has a sorted list (first external, last external)', (): void => {
expect(availableNetworks[3].displayName).toEqual('3DP network');
expect(availableNetworks[availableNetworks.length - 1].displayName).toEqual('ZERO');
});
@@ -114,7 +114,7 @@ describe('selectableNetworks', (): void => {
});
it('has a sorted list (first external, last external)', (): void => {
expect(selectableNetworks[3].displayName).toEqual('Acala');
expect(selectableNetworks[3].displayName).toEqual('3DP network');
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('xx network');
});
});
+1 -1
View File
@@ -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.1' };
export const packageInfo = { name: '@polkadot/networks', path: 'auto', type: 'auto', version: '12.2.2' };
+2 -2
View File
@@ -7,7 +7,7 @@ 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;
const other = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'packages/networks/test/ss58registry.json'), 'utf-8')) as unknown;
describe('@substrate/ss58-registry', (): void => {
it('has known values', (): void => {
@@ -22,7 +22,7 @@ describe('@substrate/ss58-registry', (): void => {
throw error;
}
fs.writeFileSync(path.join(process.cwd(), 'packages/networks/src/test/ss58registry.test.json'), json, { flag: 'w' });
fs.writeFileSync(path.join(process.cwd(), 'packages/networks/test/ss58registry.json'), json, { flag: 'w' });
}
});
});
@@ -597,7 +597,7 @@
{
"prefix": 50,
"network": "composable",
"displayName": "Composable",
"displayName": "Composable Finance",
"symbols": [
"LAYR"
],
@@ -716,7 +716,7 @@
{
"prefix": 65,
"network": "aventus",
"displayName": "AvN Mainnet",
"displayName": "Aventus Mainnet",
"symbols": [
"AVT"
],
@@ -1337,6 +1337,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",
@@ -1640,6 +1653,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",
+4 -3
View File
@@ -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" },
+18
View File
@@ -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" }
]
}
+12 -12
View File
@@ -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": ">=16"
},
"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.1",
"version": "12.2.2",
"browser": {
"crypto": false,
"stream": false
},
"main": "index.js",
"dependencies": {
"@noble/hashes": "1.3.0",
"@noble/secp256k1": "1.7.1",
"@polkadot/networks": "11.1.1",
"@polkadot/util": "11.1.1",
"@polkadot/wasm-crypto": "^7.0.3",
"@polkadot/x-bigint": "11.1.1",
"@polkadot/x-randomvalues": "11.1.1",
"@noble/curves": "1.1.0",
"@noble/hashes": "1.3.1",
"@polkadot/networks": "12.2.2",
"@polkadot/util": "12.2.2",
"@polkadot/wasm-crypto": "^7.2.1",
"@polkadot/wasm-util": "^7.2.1",
"@polkadot/x-bigint": "12.2.2",
"@polkadot/x-randomvalues": "12.2.2",
"@scure/base": "1.1.1",
"tslib": "^2.5.0",
"tweetnacl": "^1.0.3"
"tslib": "^2.5.3"
},
"peerDependencies": {
"@polkadot/util": "11.1.1"
"@polkadot/util": "12.2.2"
}
}
@@ -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 = [
+3 -3
View File
@@ -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';
@@ -8,6 +8,14 @@ import { u8aToString } from '@polkadot/util';
import { base32Decode } from './index.js';
describe('base32Decode', (): void => {
it('decodes an empty string)', (): void => {
expect(
u8aToString(
base32Decode('')
)
).toEqual('');
});
it('decodes a base32', (): void => {
expect(
u8aToString(
+4 -6
View File
@@ -65,15 +65,13 @@ export function createIs (validate: ValidateFn): ValidateFn {
/** @internal */
export function createValidate ({ chars, ipfs, type }: Config): ValidateFn {
return (value?: unknown, ipfsCompat?: boolean): value is string => {
if (!value || typeof value !== 'string') {
throw new Error(`Expected non-null, non-empty ${type} string input`);
}
if (ipfs && ipfsCompat && value[0] !== ipfs) {
if (typeof value !== 'string') {
throw new Error(`Expected ${type} string input`);
} else if (ipfs && ipfsCompat && value[0] !== ipfs) {
throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
}
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) {
if (!(chars.includes(value[i]) || (
value[i] === '=' && (
(i === value.length - 1) ||
@@ -18,10 +18,10 @@ describe('base32Validate', (): void => {
).toEqual(true);
});
it('fails on empty', (): void => {
it('does not fail on empty', (): void => {
expect(
() => base32Validate('')
).toThrow(/Expected/);
base32Validate('')
).toEqual(true);
});
it('fails on non-string', (): void => {
@@ -7,6 +7,12 @@ import { base32Decode } from '../base32/index.js';
import { base58Decode } from './index.js';
describe('base58Encode', (): void => {
it('decodes an empty string)', (): void => {
expect(
base58Decode('')
).toEqual(new Uint8Array());
});
it('encodes a base58 to a base32', (): void => {
expect(
base58Decode('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV')
@@ -8,6 +8,14 @@ import { stringToU8a } from '@polkadot/util';
import { base64Decode } from './index.js';
describe('base64Decode', (): void => {
it('decodes an empty string)', (): void => {
expect(
base64Decode('')
).toEqual(
stringToU8a('')
);
});
it('decodes a mixed base64 utf8 string (1)', (): void => {
expect(
base64Decode('aGVsbG8gd29ybGQg0J/RgNC40LLQtdGC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
+4 -2
View File
@@ -30,11 +30,13 @@ export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength: 6
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 });
}
/**
* @name blake2AsHex
* @description Creates a blake2b hex from the input.
*/
export const blake2AsHex = createAsHex(blake2AsU8a);
export const blake2AsHex = /*#__PURE__*/ createAsHex(blake2AsU8a);
+3 -2
View File
@@ -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';
-10
View File
@@ -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
View File
@@ -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])
};
}
+8 -5
View File
@@ -4,9 +4,9 @@
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';
/**
@@ -26,11 +26,14 @@ import { ed25519Sign as wasmSign, isReady } from '@polkadot/wasm-crypto';
export function ed25519Sign (message: HexString | Uint8Array | string, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
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);
}
+9 -5
View File
@@ -3,9 +3,9 @@
import type { HexString } from '@polkadot/util/types';
import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';
import { u8aToU8a } from '@polkadot/util';
import { hasBigInt, u8aToU8a } from '@polkadot/util';
import { ed25519Verify as wasmVerify, isReady } from '@polkadot/wasm-crypto';
/**
@@ -33,7 +33,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;
}
}
@@ -17,7 +17,7 @@ describe('formatAddress', () => {
it('returns fails on invalid address', () => {
expect(
() => ethereumEncode('0xnotaddress')
).toThrow(/Invalid address or publicKey passed/);
).toThrow(/Invalid address or publicKey provided/);
});
it('converts lowercase to the checksummed address', () => {
+1 -1
View File
@@ -24,7 +24,7 @@ export function ethereumEncode (addressOrPublic?: HexString | string | Uint8Arra
const u8aAddress = u8aToU8a(addressOrPublic);
if (![20, 32, 33, 65].includes(u8aAddress.length)) {
throw new Error('Invalid address or publicKey passed');
throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`);
}
const address = u8aToHex(getH160(u8aAddress), -1, false);
+4 -4
View File
@@ -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: HexString | Uint8Array | string, bitLength: 256 | 512, onlyJs?: boolean) => Uint8Array): (data: HexString | Uint8Array | string, onlyJs?: boolean) => Uint8Array {
return (data: HexString | Uint8Array | string, 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: HexString | Uint8Array | string, bitLength?: 256 | 512, onlyJs?: boolean) => Uint8Array {
return (value: HexString | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs?: boolean): Uint8Array => {
const u8a = u8aToU8a(value);
return !hasBigInt || (!onlyJs && isReady())
+1 -1
View File
@@ -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';
+2 -2
View File
@@ -39,10 +39,10 @@ export function hmacShaAsU8a (key: Uint8Array | string, data: Uint8Array, bitLen
* @name hmacSha256AsU8a
* @description creates a Hmac Sha256 Uint8Array from the key & data
*/
export const hmacSha256AsU8a = createSha(256);
export const hmacSha256AsU8a = /*#__PURE__*/ createSha(256);
/**
* @name hmacSha512AsU8a
* @description creates a Hmac Sha512 Uint8Array from the key & data
*/
export const hmacSha512AsU8a = createSha(512);
export const hmacSha512AsU8a = /*#__PURE__*/ createSha(512);
+1 -1
View File
@@ -42,4 +42,4 @@ export const keccak512AsU8a = /*#__PURE__*/ createBitHasher(512, keccakAsU8a);
* @name keccakAsHex
* @description Creates a keccak hex string from the input.
*/
export const keccakAsHex = createAsHex(keccakAsU8a);
export const keccakAsHex = /*#__PURE__*/ createAsHex(keccakAsU8a);
+1 -1
View File
@@ -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';
@@ -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/);
@@ -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 => {
+2 -1
View File
@@ -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 {
+1 -1
View File
@@ -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';
+1 -2
View File
@@ -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 => {
+1 -1
View File
@@ -5,4 +5,4 @@ import { secp256k1DeriveHard } from '../secp256k1/deriveHard.js';
import { secp256k1PairFromSeed } from '../secp256k1/pair/fromSeed.js';
import { createSeedDeriveFn } from './hdkdDerive.js';
export const keyHdkdEcdsa = createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard);
export const keyHdkdEcdsa = /*#__PURE__*/ createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard);
+1 -1
View File
@@ -4,4 +4,4 @@
import { ed25519DeriveHard, ed25519PairFromSeed } from '../ed25519/index.js';
import { createSeedDeriveFn } from './hdkdDerive.js';
export const keyHdkdEd25519 = createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard);
export const keyHdkdEd25519 = /*#__PURE__*/ createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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';
+65 -12
View File
@@ -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);
});
});
}
});
+13 -9
View File
@@ -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);
@@ -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 && 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
@@ -28,14 +28,14 @@ for (const onlyJsMnemonic of [false, true]) {
// NOTE we cannot actually use the onlyJsMnemonic flag here
const mnemonic = mnemonicGenerate(12);
describe(mnemonic, (): void => {
describe(`${mnemonic}`, (): void => {
// do iterations to check and re-check that all matches
for (const count of arrayRange(NUM_CHECKS)) {
it(`check=${count + 1}`, (): void => {
const minisecret = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', onlyJsMnemonic);
const minisecret = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', undefined, onlyJsMnemonic);
const edpub = ed25519PairFromSeed(minisecret).publicKey;
const srpub = sr25519PairFromSeed(minisecret).publicKey;
const testmini = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', onlyJsMini);
const testmini = mnemonicToMiniSecret(mnemonic, count ? `${count}` : '', undefined, onlyJsMini);
// explicit minisecret compare
expect(
@@ -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 { mnemonicValidate } from './validate.js';
await cryptoWaitReady();
@@ -13,15 +14,26 @@ describe('mnemonicValidate', (): void => {
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
it('returns true on valid', (): void => {
expect(
mnemonicValidate('seed sock milk update focus rotate barely fade car face mechanic mercy', onlyJs)
mnemonicValidate('seed sock milk update focus rotate barely fade car face mechanic mercy', undefined, onlyJs)
).toEqual(true);
});
it('returns false on invalid', (): void => {
expect(
mnemonicValidate('wine photo extra cushion basket dwarf humor cloud truck job boat submit', onlyJs)
mnemonicValidate('wine photo extra cushion basket dwarf humor cloud truck job boat submit', undefined, onlyJs)
).toEqual(false);
});
});
}
it('allows usage of a different wordlist', (): void => {
const mnemonic = 'pompier circuler pulpe injure aspect abyssal nuque boueux équerre balisage pieuvre médecin petit suffixe soleil cumuler monstre arlequin liasse pixel garrigue noble buisson scandale';
expect(
mnemonicValidate(mnemonic, frenchWords)
).toEqual(true);
expect(
mnemonicValidate(mnemonic)
).toEqual(false);
});
});
@@ -19,8 +19,8 @@ import { validateMnemonic } from './bip39.js';
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
* ```
*/
export function mnemonicValidate (mnemonic: string, onlyJs?: boolean): boolean {
return !hasBigInt || (!onlyJs && isReady())
export function mnemonicValidate (mnemonic: string, wordlist?: string[], onlyJs?: boolean): boolean {
return !hasBigInt || (!wordlist && !onlyJs && isReady())
? bip39Validate(mnemonic)
: validateMnemonic(mnemonic);
: validateMnemonic(mnemonic, wordlist);
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { default as english } from './en.js';
export { default as spanish } from './es.js';
export { default as french } from './fr.js';
export { default as italian } from './it.js';
export { default as japanese } from './jp.js';
export { default as korean } from './ko.js';
export { default as chineseSimplified } from './zh-s.js';
export { default as chineseTraditional } from './zh-t.js';
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,29 +0,0 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
/// <reference types="@polkadot/dev-test/globals.d.ts" />
import { naclBoxPairFromSecret } from '../index.js';
describe('naclBoxPairFromSecret', (): void => {
const secretKey = new Uint8Array([
18, 52, 86, 120, 144, 18, 52, 86,
120, 144, 18, 52, 86, 120, 144, 18,
18, 52, 86, 120, 144, 18, 52, 86,
120, 144, 18, 52, 86, 120, 144, 18
]);
it('generates a valid publicKey/secretKey pair', (): void => {
expect(
naclBoxPairFromSecret(secretKey)
).toEqual({
publicKey: new Uint8Array([
206, 110, 228, 222, 155, 43, 229, 254,
38, 117, 157, 116, 224, 87, 139, 171,
17, 195, 144, 167, 106, 36, 161, 28,
25, 232, 127, 47, 219, 165, 44, 102
]),
secretKey
});
});
});
@@ -1,24 +0,0 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Keypair } from '../../types.js';
import nacl from 'tweetnacl';
/**
* @name naclBoxPairFromSecret
* @summary Creates a new public/secret box keypair from a secret.
* @description
* Returns a object containing a box `publicKey` & `secretKey` generated from the supplied secret.
* @example
* <BR>
*
* ```javascript
* import { naclBoxPairFromSecret } from '@polkadot/util-crypto';
*
* naclBoxPairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
* ```
*/
export function naclBoxPairFromSecret (secret: Uint8Array): Keypair {
return nacl.box.keyPair.fromSecretKey(secret.slice(0, 32));
}
+2 -2
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import nacl from 'tweetnacl';
import { naclSecretboxOpen } from './tweetnacl.js';
/**
* @name naclDecrypt
@@ -18,5 +18,5 @@ import nacl from 'tweetnacl';
* ```
*/
export function naclDecrypt (encrypted: Uint8Array, nonce: Uint8Array, secret: Uint8Array): Uint8Array | null {
return nacl.secretbox.open(encrypted, nonce, secret) || null;
return naclSecretboxOpen(encrypted, nonce, secret);
}
+2 -3
View File
@@ -1,9 +1,8 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import nacl from 'tweetnacl';
import { randomAsU8a } from '../random/asU8a.js';
import { naclSecretbox } from './tweetnacl.js';
interface Encrypted {
encrypted: Uint8Array;
@@ -26,7 +25,7 @@ interface Encrypted {
*/
export function naclEncrypt (message: Uint8Array, secret: Uint8Array, nonce: Uint8Array = randomAsU8a(24)): Encrypted {
return {
encrypted: nacl.secretbox(message, nonce, secret),
encrypted: naclSecretbox(message, nonce, secret),
nonce
};
}
-3
View File
@@ -6,6 +6,3 @@
*/
export { naclDecrypt } from './decrypt.js';
export { naclEncrypt } from './encrypt.js';
export { naclBoxPairFromSecret } from './box/fromSecret.js';
export { naclOpen } from './open.js';
export { naclSeal } from './seal.js';
-102
View File
@@ -1,102 +0,0 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
/// <reference types="@polkadot/dev-test/globals.d.ts" />
import { ed25519PairFromString } from '../ed25519/index.js';
import { keyExtractPath, keyFromPath } from '../key/index.js';
import { naclBoxPairFromSecret, naclOpen, naclSeal } from './index.js';
describe('naclOpen', (): void => {
it('opens a sealed message by the sender', (): void => {
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
const sender = ed25519PairFromString('sender');
const receiver = ed25519PairFromString('receiver');
const senderBox = naclBoxPairFromSecret(sender.secretKey);
const receiverBox = naclBoxPairFromSecret(receiver.secretKey);
const { nonce, sealed } = naclSeal(message, senderBox.secretKey, receiverBox.publicKey);
expect(
naclOpen(sealed, nonce, senderBox.publicKey, receiverBox.secretKey)
).toEqual(
message
);
});
it('polkadot does double ratchet', () => {
const sender = ed25519PairFromString('sender');
const receiver = ed25519PairFromString('receiver');
// Make id key for identifying each other
const senderIdKey = keyFromPath(sender, keyExtractPath('//1//1//1//1').path, 'ed25519');
const receiverIdKey = keyFromPath(receiver, keyExtractPath('//2//2//2//2').path, 'ed25519');
// Receiver sends encrypting public key to receive message to decrypt with his private key
const receiverIdBoxKey = naclBoxPairFromSecret(receiverIdKey.secretKey);
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey.publicKey.toString()}`);
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
const senderIdBoxKey = naclBoxPairFromSecret(senderIdKey.secretKey);
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
const { nonce, sealed } = naclSeal(message, senderIdBoxKey.secretKey, receiverIdBoxKey.publicKey);
// console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
// Receiver opens encrypted message from the sender
let opened = naclOpen(sealed, nonce, senderIdBoxKey.publicKey, receiverIdBoxKey.secretKey);
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
// Oh no the Id key is hacked, derive Id key again from another index
const senderIdKey2 = keyFromPath(sender, keyExtractPath('//1//1//1//2').path, 'ed25519');
const receiverIdKey2 = keyFromPath(receiver, keyExtractPath('//2//2//2//3').path, 'ed25519');
// Receiver sends encrypting public key to receive message to decrypt with his private key
const receiverIdBoxKey2 = naclBoxPairFromSecret(receiverIdKey2.secretKey);
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2.publicKey.toString()}`);
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
const senderIdBoxKey2 = naclBoxPairFromSecret(senderIdKey2.secretKey);
const message2 = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
let ctx = naclSeal(message2, senderIdBoxKey2.secretKey, receiverIdBoxKey2.publicKey);
const sealed2 = ctx.sealed;
const nonce2 = ctx.nonce;
// console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
// Receiver opens encrypted message from the sender
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2.publicKey, receiverIdBoxKey2.secretKey);
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
// This time derive key for each message to send and receive
// Receiver sends encrypting public key to receive message to decrypt with his private key
const receiverIdBoxKey2One = naclBoxPairFromSecret(receiverIdBoxKey2.secretKey);
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2One.publicKey.toString()}`);
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
const senderIdBoxKey2One = naclBoxPairFromSecret(senderIdBoxKey2.secretKey);
const message3 = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
ctx = naclSeal(message3, senderIdBoxKey2One.secretKey, receiverIdBoxKey2One.publicKey);
// const sealed3 = ctx.sealed;
// const nonce3 = ctx.nonce;
// console.log(`Sender sends encrypted message to receiver ${sealed3.toString()}, ${nonce3.toString()}`);
// Receiver opens encrypted message from the sender
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2One.publicKey, receiverIdBoxKey2One.secretKey);
expect(opened).toEqual(message3);
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
});
it('returns null on invalid', (): void => {
expect(
naclOpen(new Uint8Array(), new Uint8Array(24), new Uint8Array(32), new Uint8Array(32))
).toEqual(null);
});
});
-22
View File
@@ -1,22 +0,0 @@
// Copyright 2017-2023 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import nacl from 'tweetnacl';
/**
* @name naclOpen
* @summary Opens a message using the receiver's secretKey and nonce
* @description
* Returns a message sealed by the sender, using the receiver's `secret` and `nonce`.
* @example
* <BR>
*
* ```javascript
* import { naclOpen } from '@polkadot/util-crypto';
*
* naclOpen([...], [...], [...]); // => [...]
* ```
*/
export function naclOpen (sealed: Uint8Array, nonce: Uint8Array, senderBoxPublic: Uint8Array, receiverBoxSecret: Uint8Array): Uint8Array | null {
return nacl.box.open(sealed, nonce, senderBoxPublic, receiverBoxSecret) || null;
}

Some files were not shown because too many files have changed in this diff Show More