npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ethsign-keychain-api

v1.0.3

Published

`ethsign-keychain-api` is a library for interacting with the EthSign Keychain MetaMask Snap.

Downloads

7

Readme

ethsign-keychain-api

ethsign-keychain-api is a library for interacting with the EthSign Keychain MetaMask Snap.

Installation

Run npm i ethsign-keychain-api or yarn add ethsign-keychain-api.

Usage

import useKeychain from "ethsign-keychain-api";

function ReactApp() {
  const {
    connectSnap,
    getSnap,
    getPassword,
    setPassword,
    removePassword,
    sync,
    setNeverSave,
    encrypt,
    decrypt,
    exportState,
    importState,
    getUrl,
    getUserRegistry,
    getSyncTo,
    setSyncTo
  } = useKeychain();
  ...
  return <>...</>;
}

useKeychain() will automatically call connectSnap() once. If the MetaMask popup is rejected, you will need to call connectSnap() again to use other EthSign Keychain functionality.

NOTE - Troubleshooting Crashes

The MetaMask Snaps API supports showing one popup at a time. If your code invokes the snap more than once (or before previous calls have completed), MetaMask may crash and all popups will disappear, even if the first one was already showing. Snap RPCs are not blocking within MetaMask. These snap crashes may not be present if the user has already granted appropriate access permissions, but they may be present on a new install (or where access permissions for your site have not been already granted).

For instance, calling setPassword() immediately followed by getPassword() where the user has not previously granted your site permission to their credential store will likely cause a crash: setPassword() will request access permissions through a MetaMask popup and the user will not have time to interact with the popup before getPassword() requests access permissions again. This will attempt to show two popups at the same time, and MetaMask will terminate the Keychain snap.

This can also be an issue with React.StrictMode enabled in your development environment if your function call to the snap results in a popup. React.StrictMode will render components twice, which means any useEffect() calls will run twice in immediate succession. This can result in MetaMask attempting to show two popups at the same time, which will crash the snap even if you only called the respective function once from within a useEffect().

Methods

connectSnap(params: Record<"version" | string, unknown> = {}): Promise<Response<any>>

Prompts MetaMask to install the EthSign Keychain snap. Version can be a string corresponding to a version of the EthSign Keychain Snap. Left blank, it will install the latest version.

...
const SNAP_VERSION: "0.2.6";
await connectSnap({ version: SNAP_VERSION });
...

getSnap(version: string): Promise<any>

Looks for the EthSign Keychain snap in the installed list of snaps on the user's MetaMask installation. Returns undefined if it cannot be found, or it returns the snap information if it is installed.

...
const SNAP_VERSION: "0.2.6";
await getSnap(SNAP_VERSION);
...

getPassword(url: string = getUrl()): Promise<Response<EthSignKeychainPasswordState>>

Gets the password state for a given URL. url defaults to the current URL.

...
const url = "https://ethsign.xyz";
await getPassword(url);
...

setPassword(username: string, password: string, url: string = getUrl(), controlled: boolean = true): Promise<Response<any>>

Set/update the password state for a given URL, username, and password combination. Controlled marks that this credential is controlled by an API and not created by a user - this will help the user realize that some credential entries should not be manually touched.

...
const url = "https://ethsign.xyz";
const username = "uname";
const password = "Password123";
const controlled = true;
await setPassword(username, password, url, controlled);
...

removePassword(url: string = getUrl(), username: string): Promise<Response<any>>

Remove a password entry from a URL's state given its corresponding username. url defaults to the current URL.

...
const url = "https://ethsign.xyz";
const username = "uname";
await removePassword(url, username);
...

sync(): Promise<Response<any>>

Sync the local Snap's password state with remote Arweave state.

...
await sync();
...

setNeverSave(url: string = getUrl(), neverSave: string): Promise<Response<any>>

Set whether or not we should save passwords for a given url. url defaults to the current URL.

...
const url = "https://ethsign.xyz";
const neverSave = false;
await setNeverSave(url, neverSave);
...

encrypt(data: string): Promise<Response<string>>

Encrypt a string using a receiver's public key. Fails if receiver's public key cannot be located.

...
const address = "0x985Eb8f653Ab087d4122F0C1dBc7972dF6B1642B";
const str = "Secret message.";
await encrypt(address, str);
...

decrypt(address: string, data: string): Promise<Response<string>>

Decrypts a hex string using the current user's private key.

...
const data = "04a487f5222b8423863b79424f28ddb324d825bd9d75cd7d5411ab925a53ba391e9512030a9168333bbade7038fa9411f2ac2b5e4f3b6d2109c1be5ef4a4175f4daad3c1556cb97bd2c7b62f77fd5bc0b628eb3d82ca68337520038bfba4ac7fe72dcf1497fea656757a58d0c2856d";
await decrypt(data);
...

exportState(): Promise<Response<string>>

Export the password state from the current user's EthSignKeychainState stored locally. Requires user to enter a password for encryption.

...
await exportState();
...

importState(data: string): Promise<Response<string>>

Import a user's password state, which was encrypted and exported into a JSON object containing nonce and data strings.

...
const state = {
  "success": true,
  "data": "{\"nonce\":\"M0Z4ILxRGNgdXqttekhThAvVXAYtQcRk\",\"data\":\"UyECrNKhnvzl6rBfrrgtkY8K+baBtSUqTT3kzTybxs6UHlgi8nYS3LArJAg+ZfFqEW/7dP+iEmL/TOiAEcNOkKlTBgdAquTg1F9cUaf6IWvZDLCq030j0OOBHIfQiolYDhm57fGgzxqpFXCRqAEMwvR+p4MnDdFAJE1ccXpbvxznofMqsAz0+n40sDz6SFZ6ro1kv5ZzEhkgUWyKblkHXo5fELPjNWXVxY2aBNAMVqqWoy2fFhNJHO60vHkZ18Ac3Y9hxIDLqX4NrSadRKlpwDE4wrve0D3any++vaxHf5froXZvut42V+Y0zX42n0FJPbNlY5/kuPgBM01Z5c/APzkcwjqzeHsQTk8ZOtWYL3+j6xMkFLOCZtjZX4psNFbIUwjwBjlE3MZCmCi1FXZkDaMFzFkk52XVYkz4o1KtoKa13CXA594oFS2i5OTBPrDspE3LHXwVkRdECBW7Q9QeInH6eJ+sIVgbc7ho8BZ3prPxq8Ub4K3XiC/XB7hWxaRe1uBuSiXtVOyX9PH1PJFbnKFhEL3t+eYCNS1W87qVRZvYyfFxQIf6TKN3a/jY9/OM6f8CYVfr7AvIvGxg1520hV5UVJwFwimrcJnEmJAqBRJAxZN/AI++0XqXFbo8lwueISqBy38deOiitX6Zi6cSY+5gDU2ONetOduX5O/8wo/Teu6dFyx9kQ2jDW1F/ceC19Chy0GnEIHdZTMGz3AiPRx5ltnPLNxBOjn+5Mnevo+/DmZqJOwIIqCoKTaUKatdaAE6QFKWvGbfcQvdUZyqfeEQpzsqmbl03rrH3RpSmCqJfMDSg7YmO6fq4sVFGjjQIPEhhplBTrzVWVvPHfDWIAdlrOETMFWS2zch/OD7uZJ9P2pZ0DAA0r2caqXz43cD7BOY=\"}"
};
await importState(JSON.stringify(state));
...

getUrl(): string

Get the current window's base URL for storing passwords.

...
getUrl();
...

getUserRegistry(address: string): Promise<Response<{publicAddress: string, publicKey: string}>>

Get the public key of a user given the user's public address.

...
const address = "0x985Eb8f653Ab087d4122F0C1dBc7972dF6B1642B";
await getUserRegistry(address);
...

getSyncTo(): Promise<string>

Get the remote sync location from the keychain snap.

...
await getSyncTo();
...

setSyncTo(): Promise<string>

Set the remote sync location for the snap. Returns the newly set remote sync location, or the existing location if an exception occurs.

...
const location = "arweave";
await setSyncTo(location);
...