
Security News
/Research
Popular node-ipc npm Package Infected with Credential Stealer
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.
@etherplay/connect
Advanced tools
Main connection library for Etherplay Accounts - provides seamless wallet and social authentication with session account management
Main connection library for Etherplay Accounts - provides seamless wallet and social authentication with session account management. This package combines Web3 wallet support with social login capabilities to create a unified authentication experience.
npm install @etherplay/connect
# or
pnpm add @etherplay/connect
# or
yarn add @etherplay/connect
import {createConnection} from '@etherplay/connect';
// Create a connection targeting wallet connection only
const connection = createConnection({
targetStep: 'WalletConnected',
chainInfo: {
id: 1,
name: 'Ethereum',
rpcUrls: {default: {http: ['https://eth.llamarpc.com']}},
nativeCurrency: {name: 'Ether', symbol: 'ETH', decimals: 18},
},
});
// Subscribe to connection state changes
connection.subscribe((state) => {
if (state.step === 'WalletConnected') {
console.log('Connected:', state.account.address);
}
});
// Initiate wallet connection
await connection.connect({type: 'wallet'});
import {createConnection} from '@etherplay/connect';
const connection = createConnection({
walletHost: 'https://wallet.etherplay.io', // Required for popup-based auth
chainInfo: {
id: 1,
name: 'Ethereum',
rpcUrls: {default: {http: ['https://eth.llamarpc.com']}},
nativeCurrency: {name: 'Ether', symbol: 'ETH', decimals: 18},
},
autoConnect: true, // Auto-reconnect returning users
});
// Connect via email
await connection.connect({type: 'email', mode: 'otp', email: 'user@example.com'});
// Or via OAuth
await connection.connect({type: 'oauth', provider: {id: 'google'}, usePopup: true});
The ensureConnected method provides a promise-based API that resolves when the target connection state is reached:
// Wait for wallet connection
const state = await connection.ensureConnected('WalletConnected');
console.log('Wallet connected:', state.account.address);
// Wait for full sign-in
const signedInState = await connection.ensureConnected('SignedIn');
console.log('Session account:', signedInState.account.signer.address);
| Option | Type | Required | Description |
|---|---|---|---|
chainInfo | ChainInfo | Yes | Chain configuration including id, name, rpcUrls |
targetStep | 'WalletConnected' | 'SignedIn' | No | Target connection step (default: 'SignedIn') |
walletOnly | boolean | No | Restrict to wallet-only authentication |
walletHost | string | Conditional | URL for popup-based auth (required for social login) |
signingOrigin | string | No | Origin used for signing (defaults to current origin) |
autoConnect | boolean | No | Auto-reconnect returning users (default: true) |
walletConnector | WalletConnector | No | Custom wallet connector (defaults to Ethereum) |
requestSignatureAutomaticallyIfPossible | boolean | No | Auto-request signature after wallet connection |
useCurrentAccount | 'always' | 'whenSingle' | No | Always use current wallet account |
prioritizeWalletProvider | boolean | No | Prioritize wallet for RPC calls |
requestsPerSecond | number | No | Rate limit for RPC requests |
The connection follows a state machine with these primary steps:
| Step | Description |
|---|---|
Idle | Initial state, not connected |
MechanismToChoose | Waiting for auth mechanism selection |
WalletToChoose | Multiple wallets available, waiting for selection |
WaitingForWalletConnection | Connecting to selected wallet |
ChooseWalletAccount | Multiple accounts available, waiting for selection |
WalletConnected | Wallet connected (target for WalletConnected mode) |
WaitingForSignature | Waiting for user to sign message |
PopupLaunched | Popup opened for social login |
SignedIn | Fully authenticated with session account |
When connected via wallet, additional state is available:
interface WalletState {
provider: WalletProvider;
accounts: `0x${string}`[];
accountChanged?: `0x${string}`; // Set if user switched accounts
chainId: string;
invalidChainId: boolean; // True if on wrong chain
switchingChain: 'addingChain' | 'switchingChain' | false;
status: 'connected' | 'locked' | 'disconnected';
}
// Auto-select wallet if only one available
await connection.connect({type: 'wallet'});
// Connect to specific wallet by name
await connection.connect({type: 'wallet', name: 'MetaMask'});
// Connect to specific address
await connection.connect({
type: 'wallet',
name: 'MetaMask',
address: '0x1234...',
});
await connection.connect({
type: 'email',
mode: 'otp',
email: 'user@example.com',
});
// Google
await connection.connect({
type: 'oauth',
provider: {id: 'google'},
usePopup: true,
});
// Facebook
await connection.connect({
type: 'oauth',
provider: {id: 'facebook'},
usePopup: true,
});
// Auth0
await connection.connect({
type: 'oauth',
provider: {id: 'auth0', connection: 'your-connection'},
usePopup: true,
});
await connection.connect({
type: 'mnemonic',
mnemonic: 'your twelve word phrase here...',
index: 0,
});
| Method | Description |
|---|---|
subscribe(callback) | Subscribe to state changes |
connect(mechanism?, options?) | Initiate connection |
cancel() | Cancel ongoing connection |
back(step) | Navigate back to previous step |
disconnect() | Disconnect and clear stored data |
requestSignature() | Request signature for session account |
connectToAddress(address, options?) | Connect to specific wallet address |
switchWalletChain(chainInfo?) | Switch wallet to different chain |
unlock() | Unlock locked wallet |
ensureConnected(step?, mechanism?, options?) | Promise-based connection |
isTargetStepReached(connection) | Check if target step is reached |
getSignatureForPublicKeyPublication() | Get signature for public key |
interface ConnectOptions {
requireUserConfirmationBeforeSignatureRequest?: boolean;
doNotStoreLocally?: boolean;
requestSignatureRightAway?: boolean;
}
interface EnsureConnectedOptions extends ConnectOptions {
skipChainCheck?: boolean; // Skip chain validation for WalletConnected step
}
When fully signed in, the account includes:
interface OriginAccount {
address: `0x${string}`; // Main wallet address
signer: {
origin: string; // Origin used for signing
address: `0x${string}`; // Derived session address
publicKey: `0x${string}`; // Session public key
privateKey: `0x${string}`; // Session private key
mnemonicKey: `0x${string}`; // Entropy key
};
metadata: {
email?: string;
};
mechanismUsed: Mechanism;
savedPublicKeyPublicationSignature?: `0x${string}`;
accountType: string;
}
Type guard to narrow connection state:
import {isTargetStepReached} from '@etherplay/connect';
connection.subscribe((state) => {
if (isTargetStepReached(state, 'SignedIn')) {
// state is now typed as SignedInState
console.log(state.account.signer.address);
}
});
The connection store is a Svelte store and works seamlessly with Svelte's reactivity:
<script>
import { createConnection } from '@etherplay/connect';
const connection = createConnection({
chainInfo: { id: 1, name: 'Ethereum', rpcUrls: { default: { http: ['...'] } } }
});
</script>
{#if $connection.step === 'Idle'}
<button on:click={() => connection.connect()}>Connect</button>
{:else if $connection.step === 'SignedIn'}
<p>Connected as {$connection.account.address}</p>
<button on:click={() => connection.disconnect()}>Disconnect</button>
{/if}
// Re-exported from @etherplay/alchemy
export {fromEntropyKeyToMnemonic, originPublicKeyPublicationMessage, originKeyMessage};
export type {OriginAccount};
// Re-exported from @etherplay/wallet-connector-ethereum
export type {UnderlyingEthereumProvider};
@etherplay/wallet-connector - Core wallet connector interfaces@etherplay/wallet-connector-ethereum - Ethereum wallet connector@etherplay/alchemy - Social login mechanismsMIT
FAQs
Main connection library for Etherplay Accounts - provides seamless wallet and social authentication with session account management
We found that @etherplay/connect demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.

Security News
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.

Security News
Packagist urges PHP projects to update Composer after a GitHub token format change exposed some GitHub Actions tokens in CI logs.