@metamask-previews/eth-trezor-keyring 3.1.0-38c4bd5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -0
- package/LICENSE +15 -0
- package/README.md +102 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/trezor-bridge.d.ts +18 -0
- package/dist/trezor-bridge.js +3 -0
- package/dist/trezor-bridge.js.map +1 -0
- package/dist/trezor-connect-bridge.d.ts +39 -0
- package/dist/trezor-connect-bridge.js +67 -0
- package/dist/trezor-connect-bridge.js.map +1 -0
- package/dist/trezor-keyring.d.ts +112 -0
- package/dist/trezor-keyring.js +470 -0
- package/dist/trezor-keyring.js.map +1 -0
- package/package.json +110 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [3.1.0]
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Bump `@trezor/connect-web` from `^9.0.6` to `^9.1.11` ([#195](https://github.com/MetaMask/eth-trezor-keyring/pull/195))
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Bump `@metamask/eth-sig-util` from `^7.0.0` to `^7.0.1` ([#195](https://github.com/MetaMask/eth-trezor-keyring/pull/195))
|
|
19
|
+
- Bump `@trezor/connect-plugin-ethereum` from `^9.0.1` to `^9.0.3` ([#195](https://github.com/MetaMask/eth-trezor-keyring/pull/195))
|
|
20
|
+
- Should help fixing MM pop-up closing issue ([#10896](https://github.com/MetaMask/metamask-extension/issues/10896))
|
|
21
|
+
|
|
22
|
+
## [3.0.0]
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **BREAKING**: Remove support for major node versions 14,15,17,19. Minimum Node.js version is now 16. ([#188](https://github.com/MetaMask/eth-trezor-keyring/pull/188))
|
|
27
|
+
- Bump `@metamask/eth-sig-util` from `^5.0.2` to `^7.0.0` ([#189](https://github.com/MetaMask/eth-trezor-keyring/pull/189))
|
|
28
|
+
- Bump dependency `hdkey` from `0.8.0` to `^2.1.0` ([#190](https://github.com/MetaMask/eth-trezor-keyring/pull/190))
|
|
29
|
+
|
|
30
|
+
## [2.0.0]
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Add `destroy` method to `TrezorKeyring`, which replaces `dispose` ([#179](https://github.com/MetaMask/eth-trezor-keyring/pull/179))
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **BREAKING:** Separate the bridge from the keyring ([#143](https://github.com/MetaMask/eth-trezor-keyring/pull/143))
|
|
39
|
+
- The Trezor bridge is now a separate class (`TrezorConnectBridge`), which must be constructed separately from the keyring and passed in as a constructor argument.
|
|
40
|
+
- The bridge initialization has been moved from the keyring constructor to the keyring `init` method. The bridge is expected to be passed to the keyring uninitialized, and the keyring `init` method is expected to be called after keyring construction (before the keyring is used).
|
|
41
|
+
- The keyring constructor no longer accepts keyring state. Instead, any pre-existing keyring state should be passed to the `deserialize` method after construction.
|
|
42
|
+
|
|
43
|
+
### Removed
|
|
44
|
+
|
|
45
|
+
- **BREAKING:** Remove `dispose` method from `TrezorKeyring`, which is replaced by `destroy` ([#179](https://github.com/MetaMask/eth-trezor-keyring/pull/179))
|
|
46
|
+
|
|
47
|
+
## [1.1.0]
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- Add legacy derivation path, allowing generation of accounts with the `m/44'/60'/0` path ([#175](https://github.com/MetaMask/eth-trezor-keyring/pull/175))
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- Migrate to TypeScript ([#161](https://github.com/MetaMask/eth-trezor-keyring/pull/161))
|
|
56
|
+
|
|
57
|
+
## [1.0.0]
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
|
|
61
|
+
- **BREAKING:** Rename package to use `@metamask` scope ([#160](https://github.com/MetaMask/eth-trezor-keyring/pull/160))
|
|
62
|
+
- **BREAKING:** Removed support for Node v12 in favor of v14 ([#135](https://github.com/MetaMask/eth-trezor-keyring/pull/135))
|
|
63
|
+
- Update `@ethereumjs/util`, `@ethereumjs/tx`, `@metamask/eth-sig-util` to latest versions ([#146](https://github.com/MetaMask/eth-trezor-keyring/pull/146))
|
|
64
|
+
- Bump trezor-connect - now @trezor/connect-plugin-ethereum & @trezor/connect-web - to v9 ([#133](https://github.com/MetaMask/eth-trezor-keyring/pull/133), [#163](https://github.com/MetaMask/eth-trezor-keyring/pull/163))
|
|
65
|
+
|
|
66
|
+
## [0.10.0]
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- Support for EIP-721 signTypedData_v4 ([#117](https://github.com/MetaMask/eth-trezor-keyring/pull/117))
|
|
71
|
+
|
|
72
|
+
## [0.9.1]
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- Update trezor connect to 8.2.3, so that 1.10.4 of the Model One firmware is supported ([#115](https://github.com/MetaMask/eth-trezor-keyring/pull/115))
|
|
77
|
+
|
|
78
|
+
## [0.9.0]
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
|
|
82
|
+
- Add dispose method, which exposes the TrezorConnect.dispose method, allowing consumers to explictly remove the Trezor Connect iframe ([#113](https://github.com/MetaMask/eth-trezor-keyring/pull/13))
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
|
|
86
|
+
- Fixed the signing of contract creation transactions, which require a nullish (empty string or undefined) `to` parameter ([#112](https://github.com/MetaMask/eth-trezor-keyring/pull/112))
|
|
87
|
+
|
|
88
|
+
## [0.8.0]
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- Support for EIP-1559 transactions for the Model T ([#108](https://github.com/MetaMask/eth-trezor-keyring/pull/108))
|
|
93
|
+
- Add setHdPath method, which allows setting the HD path used by the keyring to known, supported HD paths ([#107](https://github.com/MetaMask/eth-trezor-keyring/pull/107))
|
|
94
|
+
|
|
95
|
+
## [0.7.0]
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- Support new versions of ethereumjs/tx ([#88](https://github.com/metamask/eth-trezor-keyring/pull/88))
|
|
100
|
+
|
|
101
|
+
[Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@3.1.0...HEAD
|
|
102
|
+
[3.1.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@3.0.0...@metamask/eth-trezor-keyring@3.1.0
|
|
103
|
+
[3.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@2.0.0...@metamask/eth-trezor-keyring@3.0.0
|
|
104
|
+
[2.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@1.1.0...@metamask/eth-trezor-keyring@2.0.0
|
|
105
|
+
[1.1.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@1.0.0...@metamask/eth-trezor-keyring@1.1.0
|
|
106
|
+
[1.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@0.10.0...@metamask/eth-trezor-keyring@1.0.0
|
|
107
|
+
[0.10.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@0.9.1...@metamask/eth-trezor-keyring@0.10.0
|
|
108
|
+
[0.9.1]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@0.9.0...@metamask/eth-trezor-keyring@0.9.1
|
|
109
|
+
[0.9.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@0.8.0...@metamask/eth-trezor-keyring@0.9.0
|
|
110
|
+
[0.8.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-trezor-keyring@0.7.0...@metamask/eth-trezor-keyring@0.8.0
|
|
111
|
+
[0.7.0]: https://github.com/MetaMask/accounts/releases/tag/@metamask/eth-trezor-keyring@0.7.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 MetaMask
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# eth-trezor-keyring
|
|
2
|
+
|
|
3
|
+
An implementation of MetaMask's [Keyring interface](https://github.com/MetaMask/eth-simple-keyring#the-keyring-class-protocol), that uses a TREZOR hardware
|
|
4
|
+
wallet for all cryptographic operations.
|
|
5
|
+
|
|
6
|
+
In most regards, it works in the same way as
|
|
7
|
+
[eth-hd-keyring](https://github.com/MetaMask/eth-hd-keyring), but using a TREZOR
|
|
8
|
+
device. However there are a number of differences:
|
|
9
|
+
|
|
10
|
+
- Because the keys are stored in the device, operations that rely on the device
|
|
11
|
+
will fail if there is no TREZOR device attached, or a different TREZOR device
|
|
12
|
+
is attached.
|
|
13
|
+
- It does not support the `signMessage`, `signTypedData` or `exportAccount`
|
|
14
|
+
methods, because TREZOR devices do not support these operations.
|
|
15
|
+
- The method `signPersonalMessage` requires the firmware version 2.0.7+ for TREZOR Model T and 1.6.2+ on TREZOR ONE
|
|
16
|
+
- As of `trezor-connect`: `8.2.2`, passing an EIP-1559 transaction to `signTransaction`
|
|
17
|
+
requires the firmware version 2.4.2+ for TREZOR Model T, and version 1.10.4+ for TREZOR ONE.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
`yarn add @metamask/eth-trezor-keyring`
|
|
22
|
+
|
|
23
|
+
or
|
|
24
|
+
|
|
25
|
+
`npm install @metamask/eth-trezor-keyring`
|
|
26
|
+
|
|
27
|
+
## Using
|
|
28
|
+
|
|
29
|
+
In addition to all the known methods from the [Keyring class protocol](https://github.com/MetaMask/eth-simple-keyring#the-keyring-class-protocol),
|
|
30
|
+
there are a few others:
|
|
31
|
+
|
|
32
|
+
- **isUnlocked** : Returns true if we have the public key in memory, which allows to generate the list of accounts at any time
|
|
33
|
+
|
|
34
|
+
- **unlock** : Connects to the TREZOR device and exports the extended public key, which is later used to read the available ethereum addresses inside the trezor account.
|
|
35
|
+
|
|
36
|
+
- **setAccountToUnlock** : the index of the account that you want to unlock in order to use with the signTransaction and signPersonalMessage methods
|
|
37
|
+
|
|
38
|
+
- **getFirstPage** : returns the first ordered set of accounts from the TREZOR account
|
|
39
|
+
|
|
40
|
+
- **getNextPage** : returns the next ordered set of accounts from the TREZOR account based on the current page
|
|
41
|
+
|
|
42
|
+
- **getPreviousPage** : returns the previous ordered set of accounts from the TREZOR account based on the current page
|
|
43
|
+
|
|
44
|
+
- **forgetDevice** : removes all the device info from memory so the next interaction with the keyring will prompt the user to connect the TREZOR device and export the account information
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
### Setup
|
|
49
|
+
|
|
50
|
+
- Install [Node.js](https://nodejs.org) version 18
|
|
51
|
+
- If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you.
|
|
52
|
+
- Install [Yarn v3](https://yarnpkg.com/getting-started/install)
|
|
53
|
+
- Run `yarn install` to install dependencies and run any required post-install scripts
|
|
54
|
+
- **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state.
|
|
55
|
+
|
|
56
|
+
### Testing and Linting
|
|
57
|
+
|
|
58
|
+
Run `yarn test` to run the tests.
|
|
59
|
+
|
|
60
|
+
Run `yarn lint` to run the linter, or run `yarn lint:fix` to run the linter and fix any automatically fixable issues.
|
|
61
|
+
|
|
62
|
+
### Release & Publishing
|
|
63
|
+
|
|
64
|
+
The project follows the same release process as the other libraries in the MetaMask organization. The GitHub Actions [`action-create-release-pr`](https://github.com/MetaMask/action-create-release-pr) and [`action-publish-release`](https://github.com/MetaMask/action-publish-release) are used to automate the release process; see those repositories for more information about how they work.
|
|
65
|
+
|
|
66
|
+
1. Choose a release version.
|
|
67
|
+
|
|
68
|
+
- The release version should be chosen according to SemVer. Analyze the changes to see whether they include any breaking changes, new features, or deprecations, then choose the appropriate SemVer version. See [the SemVer specification](https://semver.org/) for more information.
|
|
69
|
+
|
|
70
|
+
2. If this release is backporting changes onto a previous release, then ensure there is a major version branch for that version (e.g. `1.x` for a `v1` backport release).
|
|
71
|
+
|
|
72
|
+
- The major version branch should be set to the most recent release with that major version. For example, when backporting a `v1.0.2` release, you'd want to ensure there was a `1.x` branch that was set to the `v1.0.1` tag.
|
|
73
|
+
|
|
74
|
+
3. Trigger the [`workflow_dispatch`](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) event [manually](https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow) for the `Create Release Pull Request` action to create the release PR.
|
|
75
|
+
|
|
76
|
+
- For a backport release, the base branch should be the major version branch that you ensured existed in step 2. For a normal release, the base branch should be the main branch for that repository (which should be the default value).
|
|
77
|
+
- This should trigger the [`action-create-release-pr`](https://github.com/MetaMask/action-create-release-pr) workflow to create the release PR.
|
|
78
|
+
|
|
79
|
+
4. Update the changelog to move each change entry into the appropriate change category ([See here](https://keepachangelog.com/en/1.0.0/#types) for the full list of change categories, and the correct ordering), and edit them to be more easily understood by users of the package.
|
|
80
|
+
|
|
81
|
+
- Generally any changes that don't affect consumers of the package (e.g. lockfile changes or development environment changes) are omitted. Exceptions may be made for changes that might be of interest despite not having an effect upon the published package (e.g. major test improvements, security improvements, improved documentation, etc.).
|
|
82
|
+
- Try to explain each change in terms that users of the package would understand (e.g. avoid referencing internal variables/concepts).
|
|
83
|
+
- Consolidate related changes into one change entry if it makes it easier to explain.
|
|
84
|
+
- Run `yarn auto-changelog validate --rc` to check that the changelog is correctly formatted.
|
|
85
|
+
|
|
86
|
+
5. Review and QA the release.
|
|
87
|
+
|
|
88
|
+
- If changes are made to the base branch, the release branch will need to be updated with these changes and review/QA will need to restart again. As such, it's probably best to avoid merging other PRs into the base branch while review is underway.
|
|
89
|
+
|
|
90
|
+
6. Squash & Merge the release.
|
|
91
|
+
|
|
92
|
+
- This should trigger the [`action-publish-release`](https://github.com/MetaMask/action-publish-release) workflow to tag the final release commit and publish the release on GitHub.
|
|
93
|
+
|
|
94
|
+
7. Publish the release on npm.
|
|
95
|
+
|
|
96
|
+
- Be very careful to use a clean local environment to publish the release, and follow exactly the same steps used during CI.
|
|
97
|
+
- Use `npm publish --dry-run` to examine the release contents to ensure the correct files are included. Compare to previous releases if necessary (e.g. using `https://unpkg.com/browse/[package name]@[package version]/`).
|
|
98
|
+
- Once you are confident the release contents are correct, publish the release using `npm publish`.
|
|
99
|
+
|
|
100
|
+
## Attributions
|
|
101
|
+
|
|
102
|
+
This code was inspired by [eth-ledger-keyring](https://github.com/jamespic/eth-ledger-keyring) and [eth-hd-keyring](https://github.com/MetaMask/eth-hd-keyring)
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./trezor-keyring"), exports);
|
|
18
|
+
__exportStar(require("./trezor-bridge"), exports);
|
|
19
|
+
__exportStar(require("./trezor-connect-bridge"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,kDAAgC;AAChC,0DAAwC","sourcesContent":["export * from './trezor-keyring';\nexport * from './trezor-bridge';\nexport * from './trezor-connect-bridge';\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConnectSettings, EthereumSignedTx, Manifest, PROTO, Response, Params, EthereumSignMessage, EthereumSignTransaction, EthereumSignTypedDataTypes, EthereumSignTypedHash } from '@trezor/connect-web';
|
|
2
|
+
export interface TrezorBridge {
|
|
3
|
+
model?: string;
|
|
4
|
+
init(settings: {
|
|
5
|
+
manifest: Manifest;
|
|
6
|
+
} & Partial<ConnectSettings>): Promise<void>;
|
|
7
|
+
dispose(): Promise<void>;
|
|
8
|
+
getPublicKey(params: {
|
|
9
|
+
path: string;
|
|
10
|
+
coin: string;
|
|
11
|
+
}): Response<{
|
|
12
|
+
publicKey: string;
|
|
13
|
+
chainCode: string;
|
|
14
|
+
}>;
|
|
15
|
+
ethereumSignTransaction(params: Params<EthereumSignTransaction>): Response<EthereumSignedTx>;
|
|
16
|
+
ethereumSignMessage(params: Params<EthereumSignMessage>): Response<PROTO.MessageSignature>;
|
|
17
|
+
ethereumSignTypedData<T extends EthereumSignTypedDataTypes>(params: Params<EthereumSignTypedHash<T>>): Response<PROTO.EthereumTypedDataSignature>;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trezor-bridge.js","sourceRoot":"","sources":["../src/trezor-bridge.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ConnectSettings,\n EthereumSignedTx,\n Manifest,\n PROTO,\n Response,\n Params,\n EthereumSignMessage,\n EthereumSignTransaction,\n EthereumSignTypedDataTypes,\n EthereumSignTypedHash,\n} from '@trezor/connect-web';\n\nexport interface TrezorBridge {\n model?: string;\n\n init(\n settings: {\n manifest: Manifest;\n } & Partial<ConnectSettings>,\n ): Promise<void>;\n\n dispose(): Promise<void>;\n\n // TrezorConnect.getPublicKey has two overloads\n // It is not possible to extract them from the library using utility types\n getPublicKey(params: {\n path: string;\n coin: string;\n }): Response<{ publicKey: string; chainCode: string }>;\n\n ethereumSignTransaction(\n params: Params<EthereumSignTransaction>,\n ): Response<EthereumSignedTx>;\n\n ethereumSignMessage(\n params: Params<EthereumSignMessage>,\n ): Response<PROTO.MessageSignature>;\n\n ethereumSignTypedData<T extends EthereumSignTypedDataTypes>(\n params: Params<EthereumSignTypedHash<T>>,\n ): Response<PROTO.EthereumTypedDataSignature>;\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Manifest, ConnectSettings, EthereumSignTransaction, Params, EthereumSignMessage, EthereumSignTypedDataTypes, EthereumSignTypedHash } from '@trezor/connect-web';
|
|
2
|
+
import type { TrezorBridge } from './trezor-bridge';
|
|
3
|
+
export declare class TrezorConnectBridge implements TrezorBridge {
|
|
4
|
+
model?: string;
|
|
5
|
+
trezorConnectInitiated: boolean;
|
|
6
|
+
init(settings: {
|
|
7
|
+
manifest: Manifest;
|
|
8
|
+
} & Partial<ConnectSettings>): Promise<void>;
|
|
9
|
+
dispose(): Promise<void>;
|
|
10
|
+
getPublicKey(params: {
|
|
11
|
+
path: string;
|
|
12
|
+
coin: string;
|
|
13
|
+
}): import("@trezor/connect-web").Response<{
|
|
14
|
+
xpubSegwit?: string | undefined;
|
|
15
|
+
descriptorChecksum?: string | undefined;
|
|
16
|
+
path: number[];
|
|
17
|
+
serializedPath: string;
|
|
18
|
+
childNum: number;
|
|
19
|
+
xpub: string;
|
|
20
|
+
chainCode: string;
|
|
21
|
+
publicKey: string;
|
|
22
|
+
fingerprint: number;
|
|
23
|
+
depth: number;
|
|
24
|
+
}>;
|
|
25
|
+
ethereumSignTransaction(params: Params<EthereumSignTransaction>): import("@trezor/connect-web").Response<{
|
|
26
|
+
v: string;
|
|
27
|
+
r: string;
|
|
28
|
+
s: string;
|
|
29
|
+
serializedTx: string;
|
|
30
|
+
}>;
|
|
31
|
+
ethereumSignMessage(params: Params<EthereumSignMessage>): import("@trezor/connect-web").Response<{
|
|
32
|
+
address: string;
|
|
33
|
+
signature: string;
|
|
34
|
+
}>;
|
|
35
|
+
ethereumSignTypedData<T extends EthereumSignTypedDataTypes>(params: Params<EthereumSignTypedHash<T>>): import("@trezor/connect-web").Response<{
|
|
36
|
+
address: string;
|
|
37
|
+
signature: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.TrezorConnectBridge = void 0;
|
|
27
|
+
const connect_web_1 = __importStar(require("@trezor/connect-web"));
|
|
28
|
+
class TrezorConnectBridge {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.trezorConnectInitiated = false;
|
|
31
|
+
}
|
|
32
|
+
async init(settings) {
|
|
33
|
+
connect_web_1.default.on(connect_web_1.DEVICE_EVENT, (event) => {
|
|
34
|
+
var _a;
|
|
35
|
+
if (event.type !== connect_web_1.DEVICE.CONNECT) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.model = (_a = event.payload.features) === null || _a === void 0 ? void 0 : _a.model;
|
|
39
|
+
});
|
|
40
|
+
if (this.trezorConnectInitiated) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await connect_web_1.default.init(settings);
|
|
44
|
+
this.trezorConnectInitiated = true;
|
|
45
|
+
}
|
|
46
|
+
dispose() {
|
|
47
|
+
// This removes the Trezor Connect iframe from the DOM
|
|
48
|
+
// This method is not well documented, but the code it calls can be seen
|
|
49
|
+
// here: https://github.com/trezor/connect/blob/dec4a56af8a65a6059fb5f63fa3c6690d2c37e00/src/js/iframe/builder.js#L181
|
|
50
|
+
connect_web_1.default.dispose();
|
|
51
|
+
return Promise.resolve();
|
|
52
|
+
}
|
|
53
|
+
getPublicKey(params) {
|
|
54
|
+
return connect_web_1.default.getPublicKey(params);
|
|
55
|
+
}
|
|
56
|
+
ethereumSignTransaction(params) {
|
|
57
|
+
return connect_web_1.default.ethereumSignTransaction(params);
|
|
58
|
+
}
|
|
59
|
+
ethereumSignMessage(params) {
|
|
60
|
+
return connect_web_1.default.ethereumSignMessage(params);
|
|
61
|
+
}
|
|
62
|
+
ethereumSignTypedData(params) {
|
|
63
|
+
return connect_web_1.default.ethereumSignTypedData(params);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.TrezorConnectBridge = TrezorConnectBridge;
|
|
67
|
+
//# sourceMappingURL=trezor-connect-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trezor-connect-bridge.js","sourceRoot":"","sources":["../src/trezor-connect-bridge.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAA0E;AAY1E,MAAa,mBAAmB;IAAhC;QAGE,2BAAsB,GAAG,KAAK,CAAC;IA+CjC,CAAC;IA7CC,KAAK,CAAC,IAAI,CACR,QAE4B;QAE5B,qBAAa,CAAC,EAAE,CAAC,0BAAY,EAAE,CAAC,KAAK,EAAE,EAAE;;YACvC,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAM,CAAC,OAAO,EAAE;gBACjC,OAAO;aACR;YACD,IAAI,CAAC,KAAK,GAAG,MAAA,KAAK,CAAC,OAAO,CAAC,QAAQ,0CAAE,KAAK,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,sBAAsB,EAAE;YAC/B,OAAO;SACR;QAED,MAAM,qBAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;IACrC,CAAC;IAED,OAAO;QACL,sDAAsD;QACtD,wEAAwE;QACxE,sHAAsH;QACtH,qBAAa,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,YAAY,CAAC,MAAsC;QACjD,OAAO,qBAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,uBAAuB,CAAC,MAAuC;QAC7D,OAAO,qBAAa,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,mBAAmB,CAAC,MAAmC;QACrD,OAAO,qBAAa,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,qBAAqB,CACnB,MAAwC;QAExC,OAAO,qBAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;CACF;AAlDD,kDAkDC","sourcesContent":["import TrezorConnect, { DEVICE_EVENT, DEVICE } from '@trezor/connect-web';\nimport type {\n Manifest,\n ConnectSettings,\n EthereumSignTransaction,\n Params,\n EthereumSignMessage,\n EthereumSignTypedDataTypes,\n EthereumSignTypedHash,\n} from '@trezor/connect-web';\nimport type { TrezorBridge } from './trezor-bridge';\n\nexport class TrezorConnectBridge implements TrezorBridge {\n model?: string;\n\n trezorConnectInitiated = false;\n\n async init(\n settings: {\n manifest: Manifest;\n } & Partial<ConnectSettings>,\n ) {\n TrezorConnect.on(DEVICE_EVENT, (event) => {\n if (event.type !== DEVICE.CONNECT) {\n return;\n }\n this.model = event.payload.features?.model;\n });\n\n if (this.trezorConnectInitiated) {\n return;\n }\n\n await TrezorConnect.init(settings);\n this.trezorConnectInitiated = true;\n }\n\n dispose() {\n // This removes the Trezor Connect iframe from the DOM\n // This method is not well documented, but the code it calls can be seen\n // here: https://github.com/trezor/connect/blob/dec4a56af8a65a6059fb5f63fa3c6690d2c37e00/src/js/iframe/builder.js#L181\n TrezorConnect.dispose();\n return Promise.resolve();\n }\n\n getPublicKey(params: { path: string; coin: string }) {\n return TrezorConnect.getPublicKey(params);\n }\n\n ethereumSignTransaction(params: Params<EthereumSignTransaction>) {\n return TrezorConnect.ethereumSignTransaction(params);\n }\n\n ethereumSignMessage(params: Params<EthereumSignMessage>) {\n return TrezorConnect.ethereumSignMessage(params);\n }\n\n ethereumSignTypedData<T extends EthereumSignTypedDataTypes>(\n params: Params<EthereumSignTypedHash<T>>,\n ) {\n return TrezorConnect.ethereumSignTypedData(params);\n }\n}\n"]}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import HDKey from 'hdkey';
|
|
4
|
+
import type { TypedTransaction } from '@ethereumjs/tx';
|
|
5
|
+
import type OldEthJsTransaction from 'ethereumjs-tx';
|
|
6
|
+
import { TypedMessage, SignTypedDataVersion, MessageTypes } from '@metamask/eth-sig-util';
|
|
7
|
+
import { TrezorBridge } from './trezor-bridge';
|
|
8
|
+
declare const ALLOWED_HD_PATHS: {
|
|
9
|
+
readonly "m/44'/60'/0'/0": true;
|
|
10
|
+
readonly "m/44'/60'/0'": true;
|
|
11
|
+
readonly "m/44'/1'/0'/0": true;
|
|
12
|
+
};
|
|
13
|
+
export declare const TREZOR_CONNECT_MANIFEST: {
|
|
14
|
+
email: string;
|
|
15
|
+
appUrl: string;
|
|
16
|
+
};
|
|
17
|
+
export interface TrezorControllerOptions {
|
|
18
|
+
hdPath?: string;
|
|
19
|
+
accounts?: string[];
|
|
20
|
+
page?: number;
|
|
21
|
+
perPage?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface TrezorControllerState {
|
|
24
|
+
hdPath: string;
|
|
25
|
+
accounts: readonly string[];
|
|
26
|
+
page: number;
|
|
27
|
+
paths: Record<string, number>;
|
|
28
|
+
perPage: number;
|
|
29
|
+
unlockedAccount: number;
|
|
30
|
+
}
|
|
31
|
+
export declare class TrezorKeyring extends EventEmitter {
|
|
32
|
+
#private;
|
|
33
|
+
static type: string;
|
|
34
|
+
readonly type: string;
|
|
35
|
+
accounts: readonly string[];
|
|
36
|
+
hdk: HDKey;
|
|
37
|
+
hdPath: string;
|
|
38
|
+
page: number;
|
|
39
|
+
perPage: number;
|
|
40
|
+
unlockedAccount: number;
|
|
41
|
+
paths: Record<string, number>;
|
|
42
|
+
bridge: TrezorBridge;
|
|
43
|
+
constructor({ bridge }: {
|
|
44
|
+
bridge: TrezorBridge;
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Gets the model, if known.
|
|
48
|
+
* This may be `undefined` if the model hasn't been loaded yet.
|
|
49
|
+
*
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
getModel(): string | undefined;
|
|
53
|
+
init(): Promise<void>;
|
|
54
|
+
destroy(): Promise<void>;
|
|
55
|
+
serialize(): Promise<TrezorControllerState>;
|
|
56
|
+
deserialize(opts?: TrezorControllerOptions): Promise<void>;
|
|
57
|
+
isUnlocked(): boolean;
|
|
58
|
+
unlock(): Promise<unknown>;
|
|
59
|
+
setAccountToUnlock(index: number | string): void;
|
|
60
|
+
addAccounts(n?: number): Promise<readonly string[]>;
|
|
61
|
+
getFirstPage(): Promise<{
|
|
62
|
+
address: string;
|
|
63
|
+
balance: number | null;
|
|
64
|
+
index: number;
|
|
65
|
+
}[]>;
|
|
66
|
+
getNextPage(): Promise<{
|
|
67
|
+
address: string;
|
|
68
|
+
balance: number | null;
|
|
69
|
+
index: number;
|
|
70
|
+
}[]>;
|
|
71
|
+
getPreviousPage(): Promise<{
|
|
72
|
+
address: string;
|
|
73
|
+
balance: number | null;
|
|
74
|
+
index: number;
|
|
75
|
+
}[]>;
|
|
76
|
+
getAccounts(): Promise<string[]>;
|
|
77
|
+
removeAccount(address: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Signs a transaction using Trezor.
|
|
80
|
+
*
|
|
81
|
+
* Accepts either an ethereumjs-tx or @ethereumjs/tx transaction, and returns
|
|
82
|
+
* the same type.
|
|
83
|
+
*
|
|
84
|
+
* @param address - Hex string address.
|
|
85
|
+
* @param tx - Instance of either new-style or old-style ethereumjs transaction.
|
|
86
|
+
* @returns The signed transaction, an instance of either new-style or old-style
|
|
87
|
+
* ethereumjs transaction.
|
|
88
|
+
*/
|
|
89
|
+
signTransaction(address: string, tx: TypedTransaction | OldEthJsTransaction): Promise<OldEthJsTransaction | TypedTransaction>;
|
|
90
|
+
signMessage(withAccount: string, data: string): Promise<unknown>;
|
|
91
|
+
signPersonalMessage(withAccount: string, message: string): Promise<unknown>;
|
|
92
|
+
/**
|
|
93
|
+
* EIP-712 Sign Typed Data
|
|
94
|
+
*/
|
|
95
|
+
signTypedData<T extends MessageTypes>(address: string, data: TypedMessage<T>, { version }: {
|
|
96
|
+
version: SignTypedDataVersion;
|
|
97
|
+
}): Promise<string>;
|
|
98
|
+
exportAccount(): Promise<never>;
|
|
99
|
+
forgetDevice(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Set the HD path to be used by the keyring. Only known supported HD paths are allowed.
|
|
102
|
+
*
|
|
103
|
+
* If the given HD path is already the current HD path, nothing happens. Otherwise the new HD
|
|
104
|
+
* path is set, and the wallet state is completely reset.
|
|
105
|
+
*
|
|
106
|
+
* @throws {Error] Throws if the HD path is not supported.
|
|
107
|
+
*
|
|
108
|
+
* @param hdPath - The HD path to set.
|
|
109
|
+
*/
|
|
110
|
+
setHdPath(hdPath: keyof typeof ALLOWED_HD_PATHS): void;
|
|
111
|
+
}
|
|
112
|
+
export {};
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
26
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
27
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
28
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
29
|
+
};
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
33
|
+
var _TrezorKeyring_instances, _TrezorKeyring_getPage, _TrezorKeyring_signTransaction, _TrezorKeyring_normalize, _TrezorKeyring_addressFromIndex, _TrezorKeyring_pathFromAddress;
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.TrezorKeyring = exports.TREZOR_CONNECT_MANIFEST = void 0;
|
|
36
|
+
const events_1 = require("events");
|
|
37
|
+
const ethUtil = __importStar(require("@ethereumjs/util"));
|
|
38
|
+
const hdkey_1 = __importDefault(require("hdkey"));
|
|
39
|
+
const tx_1 = require("@ethereumjs/tx");
|
|
40
|
+
const connect_plugin_ethereum_1 = require("@trezor/connect-plugin-ethereum");
|
|
41
|
+
const hdPathString = `m/44'/60'/0'/0`;
|
|
42
|
+
const SLIP0044TestnetPath = `m/44'/1'/0'/0`;
|
|
43
|
+
const legacyMewPath = `m/44'/60'/0'`;
|
|
44
|
+
const ALLOWED_HD_PATHS = {
|
|
45
|
+
[hdPathString]: true,
|
|
46
|
+
[legacyMewPath]: true,
|
|
47
|
+
[SLIP0044TestnetPath]: true,
|
|
48
|
+
};
|
|
49
|
+
const keyringType = 'Trezor Hardware';
|
|
50
|
+
const pathBase = 'm';
|
|
51
|
+
const MAX_INDEX = 1000;
|
|
52
|
+
const DELAY_BETWEEN_POPUPS = 1000;
|
|
53
|
+
exports.TREZOR_CONNECT_MANIFEST = {
|
|
54
|
+
email: 'support@metamask.io',
|
|
55
|
+
appUrl: 'https://metamask.io',
|
|
56
|
+
};
|
|
57
|
+
async function wait(ms) {
|
|
58
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx
|
|
62
|
+
*
|
|
63
|
+
* Transactions built with older versions of ethereumjs-tx have a
|
|
64
|
+
* getChainId method that newer versions do not.
|
|
65
|
+
* Older versions are mutable
|
|
66
|
+
* while newer versions default to being immutable.
|
|
67
|
+
* Expected shape and type
|
|
68
|
+
* of data for v, r and s differ (Buffer (old) vs BN (new)).
|
|
69
|
+
*
|
|
70
|
+
* @param tx
|
|
71
|
+
* @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.
|
|
72
|
+
*/
|
|
73
|
+
function isOldStyleEthereumjsTx(tx) {
|
|
74
|
+
return typeof tx.getChainId === 'function';
|
|
75
|
+
}
|
|
76
|
+
class TrezorKeyring extends events_1.EventEmitter {
|
|
77
|
+
constructor({ bridge }) {
|
|
78
|
+
super();
|
|
79
|
+
_TrezorKeyring_instances.add(this);
|
|
80
|
+
this.type = keyringType;
|
|
81
|
+
this.accounts = [];
|
|
82
|
+
this.hdk = new hdkey_1.default();
|
|
83
|
+
this.hdPath = hdPathString;
|
|
84
|
+
this.page = 0;
|
|
85
|
+
this.perPage = 5;
|
|
86
|
+
this.unlockedAccount = 0;
|
|
87
|
+
this.paths = {};
|
|
88
|
+
if (!bridge) {
|
|
89
|
+
throw new Error('Bridge is a required dependency for the keyring');
|
|
90
|
+
}
|
|
91
|
+
this.bridge = bridge;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Gets the model, if known.
|
|
95
|
+
* This may be `undefined` if the model hasn't been loaded yet.
|
|
96
|
+
*
|
|
97
|
+
* @returns
|
|
98
|
+
*/
|
|
99
|
+
getModel() {
|
|
100
|
+
return this.bridge.model;
|
|
101
|
+
}
|
|
102
|
+
init() {
|
|
103
|
+
return this.bridge.init({
|
|
104
|
+
manifest: exports.TREZOR_CONNECT_MANIFEST,
|
|
105
|
+
lazyLoad: true,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async destroy() {
|
|
109
|
+
return this.bridge.dispose();
|
|
110
|
+
}
|
|
111
|
+
async serialize() {
|
|
112
|
+
return Promise.resolve({
|
|
113
|
+
hdPath: this.hdPath,
|
|
114
|
+
accounts: this.accounts,
|
|
115
|
+
page: this.page,
|
|
116
|
+
paths: this.paths,
|
|
117
|
+
perPage: this.perPage,
|
|
118
|
+
unlockedAccount: this.unlockedAccount,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async deserialize(opts = {}) {
|
|
122
|
+
var _a, _b, _c, _d;
|
|
123
|
+
this.hdPath = (_a = opts.hdPath) !== null && _a !== void 0 ? _a : hdPathString;
|
|
124
|
+
this.accounts = (_b = opts.accounts) !== null && _b !== void 0 ? _b : [];
|
|
125
|
+
this.page = (_c = opts.page) !== null && _c !== void 0 ? _c : 0;
|
|
126
|
+
this.perPage = (_d = opts.perPage) !== null && _d !== void 0 ? _d : 5;
|
|
127
|
+
return Promise.resolve();
|
|
128
|
+
}
|
|
129
|
+
isUnlocked() {
|
|
130
|
+
var _a;
|
|
131
|
+
return Boolean((_a = this.hdk) === null || _a === void 0 ? void 0 : _a.publicKey);
|
|
132
|
+
}
|
|
133
|
+
async unlock() {
|
|
134
|
+
if (this.isUnlocked()) {
|
|
135
|
+
return Promise.resolve('already unlocked');
|
|
136
|
+
}
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
this.bridge
|
|
139
|
+
.getPublicKey({
|
|
140
|
+
path: this.hdPath,
|
|
141
|
+
coin: 'ETH',
|
|
142
|
+
})
|
|
143
|
+
.then((response) => {
|
|
144
|
+
var _a;
|
|
145
|
+
if (response.success) {
|
|
146
|
+
this.hdk.publicKey = Buffer.from(response.payload.publicKey, 'hex');
|
|
147
|
+
this.hdk.chainCode = Buffer.from(response.payload.chainCode, 'hex');
|
|
148
|
+
resolve('just unlocked');
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
reject(new Error(((_a = response.payload) === null || _a === void 0 ? void 0 : _a.error) || 'Unknown error'));
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.catch((e) => {
|
|
155
|
+
reject(new Error((e === null || e === void 0 ? void 0 : e.toString()) || 'Unknown error'));
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
setAccountToUnlock(index) {
|
|
160
|
+
this.unlockedAccount = parseInt(String(index), 10);
|
|
161
|
+
}
|
|
162
|
+
async addAccounts(n = 1) {
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
this.unlock()
|
|
165
|
+
.then((_) => {
|
|
166
|
+
const from = this.unlockedAccount;
|
|
167
|
+
const to = from + n;
|
|
168
|
+
for (let i = from; i < to; i++) {
|
|
169
|
+
const address = __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_addressFromIndex).call(this, pathBase, i);
|
|
170
|
+
if (!this.accounts.includes(address)) {
|
|
171
|
+
this.accounts = [...this.accounts, address];
|
|
172
|
+
}
|
|
173
|
+
this.page = 0;
|
|
174
|
+
}
|
|
175
|
+
resolve(this.accounts);
|
|
176
|
+
})
|
|
177
|
+
.catch((e) => {
|
|
178
|
+
reject(e);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async getFirstPage() {
|
|
183
|
+
this.page = 0;
|
|
184
|
+
return __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_getPage).call(this, 1);
|
|
185
|
+
}
|
|
186
|
+
async getNextPage() {
|
|
187
|
+
return __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_getPage).call(this, 1);
|
|
188
|
+
}
|
|
189
|
+
async getPreviousPage() {
|
|
190
|
+
return __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_getPage).call(this, -1);
|
|
191
|
+
}
|
|
192
|
+
async getAccounts() {
|
|
193
|
+
return Promise.resolve(this.accounts.slice());
|
|
194
|
+
}
|
|
195
|
+
removeAccount(address) {
|
|
196
|
+
if (!this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())) {
|
|
197
|
+
throw new Error(`Address ${address} not found in this keyring`);
|
|
198
|
+
}
|
|
199
|
+
this.accounts = this.accounts.filter((a) => a.toLowerCase() !== address.toLowerCase());
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Signs a transaction using Trezor.
|
|
203
|
+
*
|
|
204
|
+
* Accepts either an ethereumjs-tx or @ethereumjs/tx transaction, and returns
|
|
205
|
+
* the same type.
|
|
206
|
+
*
|
|
207
|
+
* @param address - Hex string address.
|
|
208
|
+
* @param tx - Instance of either new-style or old-style ethereumjs transaction.
|
|
209
|
+
* @returns The signed transaction, an instance of either new-style or old-style
|
|
210
|
+
* ethereumjs transaction.
|
|
211
|
+
*/
|
|
212
|
+
async signTransaction(address, tx) {
|
|
213
|
+
if (isOldStyleEthereumjsTx(tx)) {
|
|
214
|
+
// In this version of ethereumjs-tx we must add the chainId in hex format
|
|
215
|
+
// to the initial v value. The chainId must be included in the serialized
|
|
216
|
+
// transaction which is only communicated to ethereumjs-tx in this
|
|
217
|
+
// value. In newer versions the chainId is communicated via the 'Common'
|
|
218
|
+
// object.
|
|
219
|
+
return __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_signTransaction).call(this, address,
|
|
220
|
+
// @types/ethereumjs-tx and old ethereumjs-tx versions document
|
|
221
|
+
// this function return value as Buffer, but the actual
|
|
222
|
+
// Transaction._chainId will always be a number.
|
|
223
|
+
// See https://github.com/ethereumjs/ethereumjs-tx/blob/v1.3.7/index.js#L126
|
|
224
|
+
tx.getChainId(), tx, (payload) => {
|
|
225
|
+
tx.v = Buffer.from(payload.v, 'hex');
|
|
226
|
+
tx.r = Buffer.from(payload.r, 'hex');
|
|
227
|
+
tx.s = Buffer.from(payload.s, 'hex');
|
|
228
|
+
return tx;
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_signTransaction).call(this, address, Number(tx.common.chainId()), tx, (payload) => {
|
|
232
|
+
// Because tx will be immutable, first get a plain javascript object that
|
|
233
|
+
// represents the transaction. Using txData here as it aligns with the
|
|
234
|
+
// nomenclature of ethereumjs/tx.
|
|
235
|
+
const txData = tx.toJSON();
|
|
236
|
+
// The fromTxData utility expects a type to support transactions with a type other than 0
|
|
237
|
+
txData.type = tx.type;
|
|
238
|
+
// The fromTxData utility expects v,r and s to be hex prefixed
|
|
239
|
+
txData.v = ethUtil.addHexPrefix(payload.v);
|
|
240
|
+
txData.r = ethUtil.addHexPrefix(payload.r);
|
|
241
|
+
txData.s = ethUtil.addHexPrefix(payload.s);
|
|
242
|
+
// Adopt the 'common' option from the original transaction and set the
|
|
243
|
+
// returned object to be frozen if the original is frozen.
|
|
244
|
+
return tx_1.TransactionFactory.fromTxData(txData, {
|
|
245
|
+
common: tx.common,
|
|
246
|
+
freeze: Object.isFrozen(tx),
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
async signMessage(withAccount, data) {
|
|
251
|
+
return this.signPersonalMessage(withAccount, data);
|
|
252
|
+
}
|
|
253
|
+
// For personal_sign, we need to prefix the message:
|
|
254
|
+
async signPersonalMessage(withAccount, message) {
|
|
255
|
+
return new Promise((resolve, reject) => {
|
|
256
|
+
this.unlock()
|
|
257
|
+
.then((status) => {
|
|
258
|
+
setTimeout(() => {
|
|
259
|
+
this.bridge
|
|
260
|
+
.ethereumSignMessage({
|
|
261
|
+
path: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_pathFromAddress).call(this, withAccount),
|
|
262
|
+
message: ethUtil.stripHexPrefix(message),
|
|
263
|
+
hex: true,
|
|
264
|
+
})
|
|
265
|
+
.then((response) => {
|
|
266
|
+
var _a;
|
|
267
|
+
if (response.success) {
|
|
268
|
+
if (response.payload.address !==
|
|
269
|
+
ethUtil.toChecksumAddress(withAccount)) {
|
|
270
|
+
reject(new Error('signature doesnt match the right address'));
|
|
271
|
+
}
|
|
272
|
+
const signature = `0x${response.payload.signature}`;
|
|
273
|
+
resolve(signature);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
reject(new Error(((_a = response.payload) === null || _a === void 0 ? void 0 : _a.error) || 'Unknown error'));
|
|
277
|
+
}
|
|
278
|
+
})
|
|
279
|
+
.catch((e) => {
|
|
280
|
+
reject(new Error((e === null || e === void 0 ? void 0 : e.toString()) || 'Unknown error'));
|
|
281
|
+
});
|
|
282
|
+
// This is necessary to avoid popup collision
|
|
283
|
+
// between the unlock & sign trezor popups
|
|
284
|
+
}, status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0);
|
|
285
|
+
})
|
|
286
|
+
.catch((e) => {
|
|
287
|
+
reject(new Error((e === null || e === void 0 ? void 0 : e.toString()) || 'Unknown error'));
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* EIP-712 Sign Typed Data
|
|
293
|
+
*/
|
|
294
|
+
async signTypedData(address, data, { version }) {
|
|
295
|
+
var _a, _b;
|
|
296
|
+
const dataWithHashes = (0, connect_plugin_ethereum_1.transformTypedData)(data, version === 'V4');
|
|
297
|
+
// set default values for signTypedData
|
|
298
|
+
// Trezor is stricter than @metamask/eth-sig-util in what it accepts
|
|
299
|
+
const { types, message = {}, domain = {}, primaryType,
|
|
300
|
+
// snake_case since Trezor uses Protobuf naming conventions here
|
|
301
|
+
domain_separator_hash, // eslint-disable-line camelcase
|
|
302
|
+
message_hash, // eslint-disable-line camelcase
|
|
303
|
+
} = dataWithHashes;
|
|
304
|
+
// This is necessary to avoid popup collision
|
|
305
|
+
// between the unlock & sign trezor popups
|
|
306
|
+
const status = await this.unlock();
|
|
307
|
+
await wait(status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0);
|
|
308
|
+
const response = await this.bridge.ethereumSignTypedData({
|
|
309
|
+
path: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_pathFromAddress).call(this, address),
|
|
310
|
+
data: {
|
|
311
|
+
types: Object.assign(Object.assign({}, types), { EIP712Domain: (_a = types.EIP712Domain) !== null && _a !== void 0 ? _a : [] }),
|
|
312
|
+
message,
|
|
313
|
+
domain,
|
|
314
|
+
primaryType,
|
|
315
|
+
},
|
|
316
|
+
metamask_v4_compat: true,
|
|
317
|
+
// Trezor 1 only supports blindly signing hashes
|
|
318
|
+
domain_separator_hash,
|
|
319
|
+
message_hash: message_hash !== null && message_hash !== void 0 ? message_hash : '', // eslint-disable-line camelcase
|
|
320
|
+
});
|
|
321
|
+
if (response.success) {
|
|
322
|
+
if (ethUtil.toChecksumAddress(address) !== response.payload.address) {
|
|
323
|
+
throw new Error('signature doesnt match the right address');
|
|
324
|
+
}
|
|
325
|
+
return response.payload.signature;
|
|
326
|
+
}
|
|
327
|
+
throw new Error(((_b = response.payload) === null || _b === void 0 ? void 0 : _b.error) || 'Unknown error');
|
|
328
|
+
}
|
|
329
|
+
async exportAccount() {
|
|
330
|
+
return Promise.reject(new Error('Not supported on this device'));
|
|
331
|
+
}
|
|
332
|
+
forgetDevice() {
|
|
333
|
+
this.accounts = [];
|
|
334
|
+
this.hdk = new hdkey_1.default();
|
|
335
|
+
this.page = 0;
|
|
336
|
+
this.unlockedAccount = 0;
|
|
337
|
+
this.paths = {};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Set the HD path to be used by the keyring. Only known supported HD paths are allowed.
|
|
341
|
+
*
|
|
342
|
+
* If the given HD path is already the current HD path, nothing happens. Otherwise the new HD
|
|
343
|
+
* path is set, and the wallet state is completely reset.
|
|
344
|
+
*
|
|
345
|
+
* @throws {Error] Throws if the HD path is not supported.
|
|
346
|
+
*
|
|
347
|
+
* @param hdPath - The HD path to set.
|
|
348
|
+
*/
|
|
349
|
+
setHdPath(hdPath) {
|
|
350
|
+
if (!ALLOWED_HD_PATHS[hdPath]) {
|
|
351
|
+
throw new Error(`The setHdPath method does not support setting HD Path to ${hdPath}`);
|
|
352
|
+
}
|
|
353
|
+
// Reset HDKey if the path changes
|
|
354
|
+
if (this.hdPath !== hdPath) {
|
|
355
|
+
this.hdk = new hdkey_1.default();
|
|
356
|
+
this.accounts = [];
|
|
357
|
+
this.page = 0;
|
|
358
|
+
this.perPage = 5;
|
|
359
|
+
this.unlockedAccount = 0;
|
|
360
|
+
this.paths = {};
|
|
361
|
+
}
|
|
362
|
+
this.hdPath = hdPath;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
exports.TrezorKeyring = TrezorKeyring;
|
|
366
|
+
_TrezorKeyring_instances = new WeakSet(), _TrezorKeyring_getPage = async function _TrezorKeyring_getPage(increment) {
|
|
367
|
+
this.page += increment;
|
|
368
|
+
if (this.page <= 0) {
|
|
369
|
+
this.page = 1;
|
|
370
|
+
}
|
|
371
|
+
return new Promise((resolve, reject) => {
|
|
372
|
+
this.unlock()
|
|
373
|
+
.then((_) => {
|
|
374
|
+
const from = (this.page - 1) * this.perPage;
|
|
375
|
+
const to = from + this.perPage;
|
|
376
|
+
const accounts = [];
|
|
377
|
+
for (let i = from; i < to; i++) {
|
|
378
|
+
const address = __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_addressFromIndex).call(this, pathBase, i);
|
|
379
|
+
accounts.push({
|
|
380
|
+
address,
|
|
381
|
+
balance: null,
|
|
382
|
+
index: i,
|
|
383
|
+
});
|
|
384
|
+
this.paths[ethUtil.toChecksumAddress(address)] = i;
|
|
385
|
+
}
|
|
386
|
+
resolve(accounts);
|
|
387
|
+
})
|
|
388
|
+
.catch((e) => {
|
|
389
|
+
reject(e);
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
}, _TrezorKeyring_signTransaction =
|
|
393
|
+
/**
|
|
394
|
+
*
|
|
395
|
+
* @param address - Hex string address.
|
|
396
|
+
* @param chainId - Chain ID
|
|
397
|
+
* @param tx - Instance of either new-style or old-style ethereumjs transaction.
|
|
398
|
+
* @param handleSigning - Converts signed transaction
|
|
399
|
+
* to the same new-style or old-style ethereumjs-tx.
|
|
400
|
+
* @returns The signed transaction, an instance of either new-style or old-style
|
|
401
|
+
* ethereumjs transaction.
|
|
402
|
+
*/
|
|
403
|
+
async function _TrezorKeyring_signTransaction(address, chainId, tx, handleSigning) {
|
|
404
|
+
var _a, _b;
|
|
405
|
+
let transaction;
|
|
406
|
+
if (isOldStyleEthereumjsTx(tx)) {
|
|
407
|
+
// legacy transaction from ethereumjs-tx package has no .toJSON() function,
|
|
408
|
+
// so we need to convert to hex-strings manually manually
|
|
409
|
+
transaction = {
|
|
410
|
+
to: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.to),
|
|
411
|
+
value: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.value),
|
|
412
|
+
data: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.data),
|
|
413
|
+
chainId,
|
|
414
|
+
nonce: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.nonce),
|
|
415
|
+
gasLimit: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.gasLimit),
|
|
416
|
+
gasPrice: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, tx.gasPrice),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
// new-style transaction from @ethereumjs/tx package
|
|
421
|
+
// we can just copy tx.toJSON() for everything except chainId, which must be a number
|
|
422
|
+
transaction = Object.assign(Object.assign({}, tx.toJSON()), { chainId, to: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_normalize).call(this, ethUtil.toBuffer(tx.to)) });
|
|
423
|
+
}
|
|
424
|
+
try {
|
|
425
|
+
const status = await this.unlock();
|
|
426
|
+
await wait(status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0);
|
|
427
|
+
const response = await this.bridge.ethereumSignTransaction({
|
|
428
|
+
path: __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_pathFromAddress).call(this, address),
|
|
429
|
+
transaction,
|
|
430
|
+
});
|
|
431
|
+
if (response.success) {
|
|
432
|
+
const newOrMutatedTx = handleSigning(response.payload);
|
|
433
|
+
const addressSignedWith = ethUtil.toChecksumAddress(ethUtil.addHexPrefix(newOrMutatedTx.getSenderAddress().toString('hex')));
|
|
434
|
+
const correctAddress = ethUtil.toChecksumAddress(address);
|
|
435
|
+
if (addressSignedWith !== correctAddress) {
|
|
436
|
+
throw new Error("signature doesn't match the right address");
|
|
437
|
+
}
|
|
438
|
+
return newOrMutatedTx;
|
|
439
|
+
}
|
|
440
|
+
throw new Error(((_a = response.payload) === null || _a === void 0 ? void 0 : _a.error) || 'Unknown error');
|
|
441
|
+
}
|
|
442
|
+
catch (e) {
|
|
443
|
+
throw new Error((_b = e === null || e === void 0 ? void 0 : e.toString()) !== null && _b !== void 0 ? _b : 'Unknown error');
|
|
444
|
+
}
|
|
445
|
+
}, _TrezorKeyring_normalize = function _TrezorKeyring_normalize(buf) {
|
|
446
|
+
return ethUtil.bufferToHex(buf).toString();
|
|
447
|
+
}, _TrezorKeyring_addressFromIndex = function _TrezorKeyring_addressFromIndex(basePath, i) {
|
|
448
|
+
const dkey = this.hdk.derive(`${basePath}/${i}`);
|
|
449
|
+
const address = ethUtil
|
|
450
|
+
.publicToAddress(dkey.publicKey, true)
|
|
451
|
+
.toString('hex');
|
|
452
|
+
return ethUtil.toChecksumAddress(`0x${address}`);
|
|
453
|
+
}, _TrezorKeyring_pathFromAddress = function _TrezorKeyring_pathFromAddress(address) {
|
|
454
|
+
const checksummedAddress = ethUtil.toChecksumAddress(address);
|
|
455
|
+
let index = this.paths[checksummedAddress];
|
|
456
|
+
if (typeof index === 'undefined') {
|
|
457
|
+
for (let i = 0; i < MAX_INDEX; i++) {
|
|
458
|
+
if (checksummedAddress === __classPrivateFieldGet(this, _TrezorKeyring_instances, "m", _TrezorKeyring_addressFromIndex).call(this, pathBase, i)) {
|
|
459
|
+
index = i;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (typeof index === 'undefined') {
|
|
465
|
+
throw new Error('Unknown address');
|
|
466
|
+
}
|
|
467
|
+
return `${this.hdPath}/${index}`;
|
|
468
|
+
};
|
|
469
|
+
TrezorKeyring.type = keyringType;
|
|
470
|
+
//# sourceMappingURL=trezor-keyring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trezor-keyring.js","sourceRoot":"","sources":["../src/trezor-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from 'events';\nimport * as ethUtil from '@ethereumjs/util';\nimport HDKey from 'hdkey';\nimport type {\n EthereumTransactionEIP1559,\n EthereumSignedTx,\n EthereumTransaction,\n} from '@trezor/connect-web';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport type { TypedTransaction, TxData } from '@ethereumjs/tx';\nimport type OldEthJsTransaction from 'ethereumjs-tx';\nimport { transformTypedData } from '@trezor/connect-plugin-ethereum';\nimport {\n TypedMessage,\n SignTypedDataVersion,\n MessageTypes,\n} from '@metamask/eth-sig-util';\nimport { TrezorBridge } from './trezor-bridge';\n\nconst hdPathString = `m/44'/60'/0'/0`;\nconst SLIP0044TestnetPath = `m/44'/1'/0'/0`;\nconst legacyMewPath = `m/44'/60'/0'`;\n\nconst ALLOWED_HD_PATHS = {\n [hdPathString]: true,\n [legacyMewPath]: true,\n [SLIP0044TestnetPath]: true,\n} as const;\n\nconst keyringType = 'Trezor Hardware';\nconst pathBase = 'm';\nconst MAX_INDEX = 1000;\nconst DELAY_BETWEEN_POPUPS = 1000;\nexport const TREZOR_CONNECT_MANIFEST = {\n email: 'support@metamask.io',\n appUrl: 'https://metamask.io',\n};\n\nexport interface TrezorControllerOptions {\n hdPath?: string;\n accounts?: string[];\n page?: number;\n perPage?: number;\n}\n\nexport interface TrezorControllerState {\n hdPath: string;\n accounts: readonly string[];\n page: number;\n paths: Record<string, number>;\n perPage: number;\n unlockedAccount: number;\n}\n\nasync function wait(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Check if the given transaction is made with ethereumjs-tx or @ethereumjs/tx\n *\n * Transactions built with older versions of ethereumjs-tx have a\n * getChainId method that newer versions do not.\n * Older versions are mutable\n * while newer versions default to being immutable.\n * Expected shape and type\n * of data for v, r and s differ (Buffer (old) vs BN (new)).\n *\n * @param tx\n * @returns Returns `true` if tx is an old-style ethereumjs-tx transaction.\n */\nfunction isOldStyleEthereumjsTx(\n tx: TypedTransaction | OldEthJsTransaction,\n): tx is OldEthJsTransaction {\n return typeof (tx as OldEthJsTransaction).getChainId === 'function';\n}\n\nexport class TrezorKeyring extends EventEmitter {\n static type: string = keyringType;\n\n readonly type: string = keyringType;\n\n accounts: readonly string[] = [];\n\n hdk: HDKey = new HDKey();\n\n hdPath: string = hdPathString;\n\n page = 0;\n\n perPage = 5;\n\n unlockedAccount = 0;\n\n paths: Record<string, number> = {};\n\n bridge: TrezorBridge;\n\n constructor({ bridge }: { bridge: TrezorBridge }) {\n super();\n\n if (!bridge) {\n throw new Error('Bridge is a required dependency for the keyring');\n }\n\n this.bridge = bridge;\n }\n\n /**\n * Gets the model, if known.\n * This may be `undefined` if the model hasn't been loaded yet.\n *\n * @returns\n */\n getModel(): string | undefined {\n return this.bridge.model;\n }\n\n init() {\n return this.bridge.init({\n manifest: TREZOR_CONNECT_MANIFEST,\n lazyLoad: true,\n });\n }\n\n async destroy() {\n return this.bridge.dispose();\n }\n\n async serialize(): Promise<TrezorControllerState> {\n return Promise.resolve({\n hdPath: this.hdPath,\n accounts: this.accounts,\n page: this.page,\n paths: this.paths,\n perPage: this.perPage,\n unlockedAccount: this.unlockedAccount,\n });\n }\n\n async deserialize(opts: TrezorControllerOptions = {}) {\n this.hdPath = opts.hdPath ?? hdPathString;\n this.accounts = opts.accounts ?? [];\n this.page = opts.page ?? 0;\n this.perPage = opts.perPage ?? 5;\n return Promise.resolve();\n }\n\n isUnlocked() {\n return Boolean(this.hdk?.publicKey);\n }\n\n async unlock() {\n if (this.isUnlocked()) {\n return Promise.resolve('already unlocked');\n }\n return new Promise((resolve, reject) => {\n this.bridge\n .getPublicKey({\n path: this.hdPath,\n coin: 'ETH',\n })\n .then((response) => {\n if (response.success) {\n this.hdk.publicKey = Buffer.from(response.payload.publicKey, 'hex');\n this.hdk.chainCode = Buffer.from(response.payload.chainCode, 'hex');\n resolve('just unlocked');\n } else {\n reject(new Error(response.payload?.error || 'Unknown error'));\n }\n })\n .catch((e) => {\n reject(new Error(e?.toString() || 'Unknown error'));\n });\n });\n }\n\n setAccountToUnlock(index: number | string) {\n this.unlockedAccount = parseInt(String(index), 10);\n }\n\n async addAccounts(n = 1): Promise<readonly string[]> {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then((_) => {\n const from = this.unlockedAccount;\n const to = from + n;\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n if (!this.accounts.includes(address)) {\n this.accounts = [...this.accounts, address];\n }\n this.page = 0;\n }\n resolve(this.accounts);\n })\n .catch((e) => {\n reject(e);\n });\n });\n }\n\n async getFirstPage() {\n this.page = 0;\n return this.#getPage(1);\n }\n\n async getNextPage() {\n return this.#getPage(1);\n }\n\n async getPreviousPage() {\n return this.#getPage(-1);\n }\n\n async #getPage(\n increment: number,\n ): Promise<{ address: string; balance: number | null; index: number }[]> {\n this.page += increment;\n\n if (this.page <= 0) {\n this.page = 1;\n }\n\n return new Promise((resolve, reject) => {\n this.unlock()\n .then((_) => {\n const from = (this.page - 1) * this.perPage;\n const to = from + this.perPage;\n\n const accounts = [];\n\n for (let i = from; i < to; i++) {\n const address = this.#addressFromIndex(pathBase, i);\n accounts.push({\n address,\n balance: null,\n index: i,\n });\n this.paths[ethUtil.toChecksumAddress(address)] = i;\n }\n resolve(accounts);\n })\n .catch((e) => {\n reject(e);\n });\n });\n }\n\n async getAccounts() {\n return Promise.resolve(this.accounts.slice());\n }\n\n removeAccount(address: string) {\n if (\n !this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())\n ) {\n throw new Error(`Address ${address} not found in this keyring`);\n }\n\n this.accounts = this.accounts.filter(\n (a) => a.toLowerCase() !== address.toLowerCase(),\n );\n }\n\n /**\n * Signs a transaction using Trezor.\n *\n * Accepts either an ethereumjs-tx or @ethereumjs/tx transaction, and returns\n * the same type.\n *\n * @param address - Hex string address.\n * @param tx - Instance of either new-style or old-style ethereumjs transaction.\n * @returns The signed transaction, an instance of either new-style or old-style\n * ethereumjs transaction.\n */\n async signTransaction(\n address: string,\n tx: TypedTransaction | OldEthJsTransaction,\n ) {\n if (isOldStyleEthereumjsTx(tx)) {\n // In this version of ethereumjs-tx we must add the chainId in hex format\n // to the initial v value. The chainId must be included in the serialized\n // transaction which is only communicated to ethereumjs-tx in this\n // value. In newer versions the chainId is communicated via the 'Common'\n // object.\n return this.#signTransaction(\n address,\n // @types/ethereumjs-tx and old ethereumjs-tx versions document\n // this function return value as Buffer, but the actual\n // Transaction._chainId will always be a number.\n // See https://github.com/ethereumjs/ethereumjs-tx/blob/v1.3.7/index.js#L126\n tx.getChainId() as unknown as number,\n tx,\n (payload) => {\n tx.v = Buffer.from(payload.v, 'hex');\n tx.r = Buffer.from(payload.r, 'hex');\n tx.s = Buffer.from(payload.s, 'hex');\n return tx;\n },\n );\n }\n return this.#signTransaction(\n address,\n Number(tx.common.chainId()),\n tx,\n (payload) => {\n // Because tx will be immutable, first get a plain javascript object that\n // represents the transaction. Using txData here as it aligns with the\n // nomenclature of ethereumjs/tx.\n const txData: TxData = tx.toJSON();\n // The fromTxData utility expects a type to support transactions with a type other than 0\n txData.type = tx.type;\n // The fromTxData utility expects v,r and s to be hex prefixed\n txData.v = ethUtil.addHexPrefix(payload.v);\n txData.r = ethUtil.addHexPrefix(payload.r);\n txData.s = ethUtil.addHexPrefix(payload.s);\n // Adopt the 'common' option from the original transaction and set the\n // returned object to be frozen if the original is frozen.\n return TransactionFactory.fromTxData(txData, {\n common: tx.common,\n freeze: Object.isFrozen(tx),\n });\n },\n );\n }\n\n /**\n *\n * @param address - Hex string address.\n * @param chainId - Chain ID\n * @param tx - Instance of either new-style or old-style ethereumjs transaction.\n * @param handleSigning - Converts signed transaction\n * to the same new-style or old-style ethereumjs-tx.\n * @returns The signed transaction, an instance of either new-style or old-style\n * ethereumjs transaction.\n */\n async #signTransaction<T extends TypedTransaction | OldEthJsTransaction>(\n address: string,\n chainId: number,\n tx: T,\n handleSigning: (tx: EthereumSignedTx) => T,\n ): Promise<T> {\n let transaction: EthereumTransaction | EthereumTransactionEIP1559;\n if (isOldStyleEthereumjsTx(tx)) {\n // legacy transaction from ethereumjs-tx package has no .toJSON() function,\n // so we need to convert to hex-strings manually manually\n transaction = {\n to: this.#normalize(tx.to),\n value: this.#normalize(tx.value),\n data: this.#normalize(tx.data),\n chainId,\n nonce: this.#normalize(tx.nonce),\n gasLimit: this.#normalize(tx.gasLimit),\n gasPrice: this.#normalize(tx.gasPrice),\n };\n } else {\n // new-style transaction from @ethereumjs/tx package\n // we can just copy tx.toJSON() for everything except chainId, which must be a number\n transaction = {\n ...tx.toJSON(),\n chainId,\n to: this.#normalize(ethUtil.toBuffer(tx.to)),\n } as EthereumTransaction | EthereumTransactionEIP1559;\n }\n\n try {\n const status = await this.unlock();\n await wait(status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0);\n const response = await this.bridge.ethereumSignTransaction({\n path: this.#pathFromAddress(address),\n transaction,\n });\n if (response.success) {\n const newOrMutatedTx = handleSigning(response.payload);\n\n const addressSignedWith = ethUtil.toChecksumAddress(\n ethUtil.addHexPrefix(\n newOrMutatedTx.getSenderAddress().toString('hex'),\n ),\n );\n const correctAddress = ethUtil.toChecksumAddress(address);\n if (addressSignedWith !== correctAddress) {\n throw new Error(\"signature doesn't match the right address\");\n }\n\n return newOrMutatedTx;\n }\n throw new Error(response.payload?.error || 'Unknown error');\n } catch (e) {\n throw new Error(e?.toString() ?? 'Unknown error');\n }\n }\n\n async signMessage(withAccount: string, data: string) {\n return this.signPersonalMessage(withAccount, data);\n }\n\n // For personal_sign, we need to prefix the message:\n async signPersonalMessage(withAccount: string, message: string) {\n return new Promise((resolve, reject) => {\n this.unlock()\n .then((status) => {\n setTimeout(\n () => {\n this.bridge\n .ethereumSignMessage({\n path: this.#pathFromAddress(withAccount),\n message: ethUtil.stripHexPrefix(message),\n hex: true,\n })\n .then((response) => {\n if (response.success) {\n if (\n response.payload.address !==\n ethUtil.toChecksumAddress(withAccount)\n ) {\n reject(\n new Error('signature doesnt match the right address'),\n );\n }\n const signature = `0x${response.payload.signature}`;\n resolve(signature);\n } else {\n reject(\n new Error(response.payload?.error || 'Unknown error'),\n );\n }\n })\n .catch((e) => {\n reject(new Error(e?.toString() || 'Unknown error'));\n });\n // This is necessary to avoid popup collision\n // between the unlock & sign trezor popups\n },\n status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0,\n );\n })\n .catch((e) => {\n reject(new Error(e?.toString() || 'Unknown error'));\n });\n });\n }\n\n /**\n * EIP-712 Sign Typed Data\n */\n async signTypedData<T extends MessageTypes>(\n address: string,\n data: TypedMessage<T>,\n { version }: { version: SignTypedDataVersion },\n ) {\n const dataWithHashes = transformTypedData(data, version === 'V4');\n\n // set default values for signTypedData\n // Trezor is stricter than @metamask/eth-sig-util in what it accepts\n const {\n types,\n message = {},\n domain = {},\n primaryType,\n // snake_case since Trezor uses Protobuf naming conventions here\n domain_separator_hash, // eslint-disable-line camelcase\n message_hash, // eslint-disable-line camelcase\n } = dataWithHashes;\n\n // This is necessary to avoid popup collision\n // between the unlock & sign trezor popups\n const status = await this.unlock();\n await wait(status === 'just unlocked' ? DELAY_BETWEEN_POPUPS : 0);\n\n const response = await this.bridge.ethereumSignTypedData({\n path: this.#pathFromAddress(address),\n data: {\n types: { ...types, EIP712Domain: types.EIP712Domain ?? [] },\n message,\n domain,\n primaryType,\n },\n metamask_v4_compat: true, // eslint-disable-line camelcase\n // Trezor 1 only supports blindly signing hashes\n domain_separator_hash, // eslint-disable-line camelcase\n message_hash: message_hash ?? '', // eslint-disable-line camelcase\n });\n\n if (response.success) {\n if (ethUtil.toChecksumAddress(address) !== response.payload.address) {\n throw new Error('signature doesnt match the right address');\n }\n return response.payload.signature;\n }\n\n throw new Error(response.payload?.error || 'Unknown error');\n }\n\n async exportAccount() {\n return Promise.reject(new Error('Not supported on this device'));\n }\n\n forgetDevice() {\n this.accounts = [];\n this.hdk = new HDKey();\n this.page = 0;\n this.unlockedAccount = 0;\n this.paths = {};\n }\n\n /**\n * Set the HD path to be used by the keyring. Only known supported HD paths are allowed.\n *\n * If the given HD path is already the current HD path, nothing happens. Otherwise the new HD\n * path is set, and the wallet state is completely reset.\n *\n * @throws {Error] Throws if the HD path is not supported.\n *\n * @param hdPath - The HD path to set.\n */\n setHdPath(hdPath: keyof typeof ALLOWED_HD_PATHS) {\n if (!ALLOWED_HD_PATHS[hdPath]) {\n throw new Error(\n `The setHdPath method does not support setting HD Path to ${hdPath}`,\n );\n }\n\n // Reset HDKey if the path changes\n if (this.hdPath !== hdPath) {\n this.hdk = new HDKey();\n this.accounts = [];\n this.page = 0;\n this.perPage = 5;\n this.unlockedAccount = 0;\n this.paths = {};\n }\n this.hdPath = hdPath;\n }\n\n #normalize(buf: Buffer) {\n return ethUtil.bufferToHex(buf).toString();\n }\n\n #addressFromIndex(basePath: string, i: number) {\n const dkey = this.hdk.derive(`${basePath}/${i}`);\n const address = ethUtil\n .publicToAddress(dkey.publicKey, true)\n .toString('hex');\n return ethUtil.toChecksumAddress(`0x${address}`);\n }\n\n #pathFromAddress(address: string) {\n const checksummedAddress = ethUtil.toChecksumAddress(address);\n let index = this.paths[checksummedAddress];\n if (typeof index === 'undefined') {\n for (let i = 0; i < MAX_INDEX; i++) {\n if (checksummedAddress === this.#addressFromIndex(pathBase, i)) {\n index = i;\n break;\n }\n }\n }\n\n if (typeof index === 'undefined') {\n throw new Error('Unknown address');\n }\n return `${this.hdPath}/${index}`;\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@metamask-previews/eth-trezor-keyring",
|
|
3
|
+
"version": "3.1.0-38c4bd5",
|
|
4
|
+
"description": "A MetaMask compatible keyring, for trezor hardware wallets",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ethereum",
|
|
7
|
+
"keyring",
|
|
8
|
+
"trezor",
|
|
9
|
+
"metamask"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/metamask/eth-trezor-keyring#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/metamask/eth-trezor-keyring/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/MetaMask/eth-trezor-keyring.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"author": "Bruno Barbieri",
|
|
21
|
+
"main": "dist/index.js",
|
|
22
|
+
"types": "dist/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist/"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc --build tsconfig.build.json",
|
|
28
|
+
"build:clean": "rimraf dist && yarn build",
|
|
29
|
+
"build:docs": "typedoc",
|
|
30
|
+
"build:force": "tsc --build tsconfig.build.json --force",
|
|
31
|
+
"changelog:update": "../../scripts/update-changelog.sh @metamask/eth-trezor-keyring",
|
|
32
|
+
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/eth-trezor-keyring",
|
|
33
|
+
"publish:preview": "yarn npm publish --tag preview",
|
|
34
|
+
"test": "jest && jest-it-up",
|
|
35
|
+
"test:clean": "jest --clearCache",
|
|
36
|
+
"test:verbose": "jest --verbose",
|
|
37
|
+
"test:watch": "jest --watch"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@ethereumjs/tx": "^4.0.0",
|
|
41
|
+
"@ethereumjs/util": "^8.0.0",
|
|
42
|
+
"@metamask/eth-sig-util": "^7.0.1",
|
|
43
|
+
"@trezor/connect-plugin-ethereum": "^9.0.3",
|
|
44
|
+
"@trezor/connect-web": "^9.1.11",
|
|
45
|
+
"deepmerge": "^4.2.2",
|
|
46
|
+
"hdkey": "^2.1.0",
|
|
47
|
+
"jest-environment-jsdom": "^29.7.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@ethereumjs/common": "^3.0.0",
|
|
51
|
+
"@lavamoat/allow-scripts": "^3.0.4",
|
|
52
|
+
"@metamask/auto-changelog": "^3.0.0",
|
|
53
|
+
"@types/ethereumjs-tx": "^1.0.1",
|
|
54
|
+
"@types/hdkey": "^2.0.1",
|
|
55
|
+
"@types/jest": "^28.1.6",
|
|
56
|
+
"@types/node": "^16.18.57",
|
|
57
|
+
"@types/sinon": "^9.0.10",
|
|
58
|
+
"@types/w3c-web-usb": "^1.0.6",
|
|
59
|
+
"depcheck": "^1.4.3",
|
|
60
|
+
"ethereumjs-tx": "^1.3.4",
|
|
61
|
+
"jest": "^28.1.3",
|
|
62
|
+
"jest-it-up": "^2.2.0",
|
|
63
|
+
"rimraf": "^4.1.2",
|
|
64
|
+
"sinon": "^9.2.3",
|
|
65
|
+
"ts-jest": "^28.0.7",
|
|
66
|
+
"ts-node": "^10.7.0",
|
|
67
|
+
"typedoc": "^0.23.15",
|
|
68
|
+
"typescript": "~4.8.4"
|
|
69
|
+
},
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": "^18.18 || >=20"
|
|
72
|
+
},
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public",
|
|
75
|
+
"registry": "https://registry.npmjs.org/"
|
|
76
|
+
},
|
|
77
|
+
"installConfig": {
|
|
78
|
+
"hoistingLimits": "workspaces"
|
|
79
|
+
},
|
|
80
|
+
"lavamoat": {
|
|
81
|
+
"allowScripts": {
|
|
82
|
+
"keccak": false,
|
|
83
|
+
"secp256k1": false,
|
|
84
|
+
"@lavamoat/preinstall-always-fail": false,
|
|
85
|
+
"core-js": false,
|
|
86
|
+
"blake-hash": false,
|
|
87
|
+
"tiny-secp256k1": false,
|
|
88
|
+
"protobufjs": false,
|
|
89
|
+
"ethereumjs-tx>ethereumjs-util>keccak": false,
|
|
90
|
+
"ethereumjs-util>ethereum-cryptography>keccak": false,
|
|
91
|
+
"ethereumjs-util>ethereum-cryptography>secp256k1": false,
|
|
92
|
+
"hdkey>secp256k1": false,
|
|
93
|
+
"trezor-connect>@trezor/transport>protobufjs": false,
|
|
94
|
+
"trezor-connect>@trezor/utxo-lib>blake-hash": false,
|
|
95
|
+
"trezor-connect>@trezor/utxo-lib>tiny-secp256k1": false,
|
|
96
|
+
"@trezor/connect-web>@trezor/connect>@trezor/transport>protobufjs": false,
|
|
97
|
+
"@trezor/connect-web>@trezor/connect>@trezor/utxo-lib>blake-hash": false,
|
|
98
|
+
"@trezor/connect-web>@trezor/connect>@trezor/utxo-lib>tiny-secp256k1": false,
|
|
99
|
+
"@ethereumjs/tx>ethereumjs-util>ethereum-cryptography>keccak": false,
|
|
100
|
+
"@ethereumjs/tx>ethereumjs-util>ethereum-cryptography>secp256k1": false,
|
|
101
|
+
"ethereumjs-tx>ethereumjs-util>ethereum-cryptography>keccak": false,
|
|
102
|
+
"ethereumjs-tx>ethereumjs-util>ethereum-cryptography>secp256k1": false,
|
|
103
|
+
"@trezor/connect-web>@trezor/connect>@trezor/blockchain-link>@solana/web3.js>bigint-buffer": false,
|
|
104
|
+
"@trezor/connect-web>@trezor/connect>@trezor/blockchain-link>ws>bufferutil": false,
|
|
105
|
+
"@trezor/connect-web>@trezor/connect>@trezor/blockchain-link>ws>utf-8-validate": false,
|
|
106
|
+
"@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": false,
|
|
107
|
+
"@trezor/connect-web>@trezor/connect>@trezor/transport>usb": false
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|