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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@etherplay/wallet-connector

v0.2.0

Published

Core wallet connector interfaces and types for @etherplay/connect - provides the foundation for wallet provider implementations across different blockchain networks

Readme

@etherplay/wallet-connector

Core wallet connector interfaces and types for the @etherplay/connect ecosystem. This package provides the foundational abstractions for wallet provider implementations across different blockchain networks.

Installation

npm install @etherplay/wallet-connector
# or
pnpm add @etherplay/wallet-connector
# or
yarn add @etherplay/wallet-connector

Overview

This package defines the core interfaces and types used by wallet connector implementations. It serves as the foundation for building wallet integrations that work consistently across different blockchain networks.

Core Types

WalletHandle

Represents a wallet with its provider and metadata:

type WalletHandle<UnderlyingProvider> = {
	walletProvider: WalletProvider<UnderlyingProvider>;
	info: WalletInfo;
};

WalletInfo

Metadata about a wallet:

type WalletInfo = {
	uuid: string;
	name: string;
	icon: string;
	rdns: string;
	// This wallet answers by itself: it puts nothing on the user's screen and waits for nobody.
	// Absent means it prompts.
	autoApproves?: boolean;
};

// The question the other way round, with the default in one place.
function walletPrompts(info: WalletInfo | undefined): boolean;

autoApproves is a declaration beside the name and the icon, because it is the same kind of fact: something only the wallet knows, which cannot be inferred from the outside (a generated in-tab key and a browser extension expose the same provider surface). Only a wallet that is CONSTRUCTED with a key it holds itself can honestly set it: a chain running in the browser tab, a burner signer, a custodian answering over RPC.

Absent means loud, so every discovered wallet and every existing caller is unaffected. The polarity is deliberate: if (info.autoApproves) is the safe reading when the field is missing, whereas a field named prompts would make !info.prompts claim "never prompts" about every ordinary wallet. Use walletPrompts(info) rather than reading the field, so the default is not re-derived per consumer.

It says nothing about speed and nothing about trust. It is exactly the claim "there is no dialog to wait for", and @etherplay/connect acts on it in exactly one way: it announces no PendingRequest for such a wallet. See ADR-0005.

ChainInfo

Information about a blockchain network:

type ChainInfo = Readonly<{
	chainId: `0x${string}`;
	rpcUrls?: readonly string[];
	blockExplorerUrls?: readonly string[];
	chainName?: string;
	iconUrls?: readonly string[];
	nativeCurrency?: Readonly<{
		name: string;
		symbol: string;
		decimals: number;
	}>;
}>;

Interfaces

AccountGenerator

Interface for generating accounts from mnemonics:

interface AccountGenerator {
	fromMnemonicToAccount(mnemonic: string, index: number): PrivateKeyAccount;
	signTextMessage(message: string, privateKey: `0x${string}`): Promise<`0x${string}`>;
	type: string;
}

WalletConnector

Main interface for wallet connector implementations:

interface WalletConnector<UnderlyingProvider> {
	fetchWallets(walletAnnounced: (walletHandle: WalletHandle<UnderlyingProvider>) => void): void;
	createAlwaysOnProvider(params: {
		endpoint: string | UnderlyingProvider;
		chainId: string;
		prioritizeWalletProvider?: boolean;
		requestsPerSecond?: number;
	}): AlwaysOnProviderWrapper<UnderlyingProvider>;
	accountGenerator: AccountGenerator;
}

WalletProvider

Interface for wallet provider interactions:

interface WalletProvider<UnderlyingProvider> extends BasicWalletProvider<UnderlyingProvider> {
	listenForAccountsChanged: (handler: (accounts: `0x${string}`[]) => void) => void;
	stopListenForAccountsChanged: (handler: (accounts: `0x${string}`[]) => void) => void;
	listenForChainChanged: (handler: (chainId: `0x${string}`) => void) => void;
	stopListenForChainChanged: (handler: (chainId: `0x${string}`) => void) => void;
	switchChain: (chainId: `0x${string}`) => Promise<null | any>;
	addChain(chainInfo: ChainInfo): Promise<null | any>;
}

AlwaysOnProviderWrapper

Wrapper for providers that should always be available, and the single place every wallet-reaching request is announced from:

interface AlwaysOnProviderWrapper<WalletProviderType> {
	setWalletProvider: (walletProvider: WalletProviderType | undefined) => void;
	setWalletStatus: (newStatus: 'connected' | 'locked' | 'disconnected') => void;
	chainId: string;
	provider: WalletProviderType;

	// Ask the wallet to sign text, ANNOUNCED. A separate surface from `provider.request` because
	// that path speaks for one chain and refuses signing methods when the wallet is elsewhere,
	// while a text signature is chain-independent.
	signMessage: (
		message: string,
		account: `0x${string}`,
		options?: {purpose?: RequestPurpose},
	) => Promise<`0x${string}`>;

	// Request tracking. `onRequest` returns an unsubscribe function.
	onRequest: (handler: RequestEventHandler) => () => void;
	getPendingRequests: () => PendingRequest[];
}

A request the user must answer and the app cannot see is a request nothing can explain, cancel or recover from, and the failure is silent: the request still works and returns the right bytes, while the only symptom is an unexplained wallet popup. So an implementation must announce everything that reaches the user's wallet, and signMessage exists so that a signature the library itself needs is reported like any other request. See ADR-0001.

PendingRequest.purpose says WHY, for requests this library originates ('delegation' | 'public-key-publication'). It is absent when the app asked directly through provider, where the app already knows what it sent. PendingRequest.account says WHO must answer it: the signer of a signature, the from of a transaction. A request can outlive the wallet state it started under, because the user may switch wallet or account while one is outstanding, so a consumer needs it to avoid pointing them at a wallet that cannot answer.

getPendingRequests() is authoritative. A consumer that rebuilds wallet state while a request is outstanding must copy the current list from it rather than assume an empty one: assuming empty erases the request permanently, because the next event for it is the one that ends it.

Usage

This package is primarily used as a dependency for implementing blockchain-specific wallet connectors:

import type {WalletConnector, WalletProvider, AccountGenerator, ChainInfo} from '@etherplay/wallet-connector';

// Implement a custom wallet connector
class MyWalletConnector implements WalletConnector<MyProvider> {
	// ... implementation
}

Related Packages

License

MIT