Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/validate-pr-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
keyring-snap-client
keyring-snap-sdk
keyring-utils
keyring-watch-only
account-api
account-api/mocks
subjectPattern: '^(?![A-Z]).+$'
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This repository contains the following packages [^fn1]:
- [`@metamask/keyring-snap-client`](packages/keyring-snap-client)
- [`@metamask/keyring-snap-sdk`](packages/keyring-snap-sdk)
- [`@metamask/keyring-utils`](packages/keyring-utils)
- [`@metamask/watch-only-keyring`](packages/keyring-watch-only)

<!-- end package list -->

Expand Down Expand Up @@ -61,6 +62,7 @@ linkStyle default opacity:0.5
keyring_snap_client(["@metamask/keyring-snap-client"]);
keyring_snap_sdk(["@metamask/keyring-snap-sdk"]);
keyring_utils(["@metamask/keyring-utils"]);
watch_only_keyring(["@metamask/watch-only-keyring"]);
account_api --> keyring_api;
account_api --> keyring_utils;
keyring_api --> keyring_utils;
Expand Down Expand Up @@ -107,6 +109,9 @@ linkStyle default opacity:0.5
keyring_snap_client --> keyring_utils;
keyring_snap_sdk --> keyring_utils;
keyring_snap_sdk --> keyring_api;
watch_only_keyring --> keyring_api;
watch_only_keyring --> keyring_sdk;
watch_only_keyring --> keyring_utils;
```

<!-- end dependency graph -->
Expand Down
1 change: 1 addition & 0 deletions packages/keyring-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Includes an optional `accountType` field, matching `private-key:import`, since the account type cannot always be detected from the address alone.
- Includes an optional `scopes` field, since the scope cannot always be detected from the address alone (e.g. an EVM address is valid on every EVM chain). When omitted, the keyring decides the scopes.
- Add `address` capability to `KeyringCapabilities`, declaring whether a keyring supports importing watch-only accounts by address ([#643](https://github.com/MetaMask/accounts/pull/643))
- Add `KeyringType.WatchOnly` keyring type ([#644](https://github.com/MetaMask/accounts/pull/644))

## [24.1.0]

Expand Down
6 changes: 6 additions & 0 deletions packages/keyring-api/src/v2/api/keyring-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,10 @@ export enum KeyringType {
* Represents keyring for money accounts.
*/
Money = 'money',

/**
* Represents a watch-only keyring that holds accounts imported by address,
* without any signing capability.
*/
WatchOnly = 'watch-only',
}
1 change: 1 addition & 0 deletions packages/keyring-api/src/v2/api/keyring.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ expectAssignable<KeyringType>(KeyringType.Snap);
expectAssignable<KeyringType>(KeyringType.Ledger);
expectAssignable<KeyringType>(KeyringType.Lattice);
expectAssignable<KeyringType>(KeyringType.Trezor);
expectAssignable<KeyringType>(KeyringType.WatchOnly);

// Test AccountCreationType enum
expectAssignable<AccountCreationType>(AccountCreationType.Bip44DerivePath);
Expand Down
18 changes: 18 additions & 0 deletions packages/keyring-watch-only/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Initial release of `@metamask/watch-only-keyring` ([#644](https://github.com/MetaMask/accounts/pull/644))
- A watch-only v2 `Keyring` that holds accounts imported by address, without any signing capability.
- Supports creating accounts via the `address:import` option, with an optional `accountType` (defaulting to `eip155:eoa`) and optional `scopes` (defaulting to the keyring's scopes, since the scope cannot always be detected from the address alone).
- Includes `WatchOnlyKeyringV1Adapter`, which adapts the keyring to the legacy v1 keyring API for `KeyringController` compatibility, adding address-based account removal.
- Includes synchronous `lookupAccount` and `lookupByAddress` methods for `AccountsController` integration.

[Unreleased]: https://github.com/MetaMask/accounts/
15 changes: 15 additions & 0 deletions packages/keyring-watch-only/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ISC License

Copyright (c) 2020 MetaMask

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 changes: 26 additions & 0 deletions packages/keyring-watch-only/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Watch-Only Keyring

A watch-only keyring that holds accounts imported by address, without any
signing capability.

Watch-only accounts make it possible to track addresses as first-class
[`KeyringAccount`](https://github.com/MetaMask/accounts/tree/main/packages/keyring-api)
objects without holding any secret material. The keyring is a v2-only
[`Keyring`](https://github.com/MetaMask/accounts/tree/main/packages/keyring-api)
implementation: it cannot sign (`submitRequest` always throws), cannot export
accounts, and its accounts declare no methods.

EVM addresses are supported for now. Addresses are validated and normalized to
their EIP-55 checksum representation.

## Installation

`yarn add @metamask/watch-only-keyring`

or

`npm install @metamask/watch-only-keyring`

## Contributing

This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/accounts#readme).
19 changes: 19 additions & 0 deletions packages/keyring-watch-only/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* For a detailed explanation regarding each configuration property and type check, visit:
* https://jestjs.io/docs/configuration
*/

const merge = require('deepmerge');
const path = require('path');

const baseConfig = require('../../jest.config.packages');

const displayName = path.basename(__dirname);

module.exports = merge(baseConfig, {
// The display name when running multiple projects
displayName,

// The glob patterns Jest uses to detect test files
testMatch: ['**/*.test.[jt]s?(x)'],
});
84 changes: 84 additions & 0 deletions packages/keyring-watch-only/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"name": "@metamask/watch-only-keyring",
"version": "0.1.0",
"description": "A watch-only keyring that holds accounts imported by address, without any signing capability",
"keywords": [
"ethereum",
"keyring",
"watch-only"
],
"homepage": "https://github.com/MetaMask/accounts/tree/main/packages/keyring-watch-only#readme",
"bugs": {
"url": "https://github.com/MetaMask/accounts/issues"
},
"license": "ISC",
"repository": {
"type": "git",
"url": "https://github.com/MetaMask/accounts.git"
},
"files": [
"dist/"
],
"sideEffects": false,
"main": "./dist/index.cjs",
"types": "./dist/index.d.cts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
"build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
"build:clean": "yarn build --clean",
"build:docs": "typedoc",
"changelog:update": "../../scripts/update-changelog.sh @metamask/watch-only-keyring",
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/watch-only-keyring",
"publish:preview": "yarn npm publish --tag preview",
"since-latest-release": "../../scripts/since-latest-release.sh",
"test": "yarn test:source && yarn test:types",
"test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
"test:source": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
"test:types": "../../scripts/tsd-test.sh ./src",
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
},
"dependencies": {
"@metamask/keyring-api": "^24.1.0",
"@metamask/keyring-sdk": "^3.1.0",
"@metamask/keyring-utils": "^5.0.0",
"@metamask/superstruct": "^3.4.1",
"@metamask/utils": "^11.11.0",
"async-mutex": "^0.5.0"
},
"devDependencies": {
"@lavamoat/allow-scripts": "^3.2.1",
"@lavamoat/preinstall-always-fail": "^2.1.0",
"@metamask/auto-changelog": "^6.1.0",
"@ts-bridge/cli": "^0.6.3",
"@types/jest": "^29.5.12",
"deepmerge": "^4.2.2",
"jest": "^29.5.0",
"typescript": "~5.3.3"
},
"engines": {
"node": ">=22"
},
"lavamoat": {
"allowScripts": {
"@lavamoat/preinstall-always-fail": false
}
}
}
2 changes: 2 additions & 0 deletions packages/keyring-watch-only/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './watch-only-keyring';
export * from './watch-only-keyring-v1-adapter';
Loading
Loading