Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

ENC Wallet Extension

The ENC Wallet Extension is a Chrome (MV3) browser extension that custodies a user's ENC identity and signs on behalf of apps — so an app never touches the private key. It's a BIP-39 seed-phrase HD wallet (an ENC Schnorr identity plus an EVM address) that injects a window.enc provider any ENC web app connects to through a standard Connect-Wallet flow. It's also NIP-07-compatible (mirrored as window.nostr).

This is the delegated-custody signer in ENC's identity model: the identity_priv stays inside the extension; the page asks it to sign, derive, or encrypt and gets results back — never the key.

Connecting from an app

// the provider is injected on page load; wait for it if it isn't there yet
if (!window.enc) await new Promise(r => window.addEventListener('encReady', r, { once: true }))
 
const { approved, pubKey, evmAddress } = await window.enc.connect()  // first call shows an approval popup
if (approved) console.log('ENC identity:', pubKey)                   // x-only 32-byte hex

Once connected, signing and encryption calls run without a popup (the user approved the origin); only connect() and sendTransaction() prompt.

The window.enc provider

Connection & accounts

MethodReturnsNotes
connect(){ approved, pubKey, evmAddress }approval popup on first use
getPublicKey()stringx-only 32-byte hex (the ENC identity)
getEvmAddress()stringcached 0x… address
isConnected()boolean
getAccounts(){ accounts: [{ index, pubKey, evmAddress }] }HD-derived accounts
switchAccount(index){ pubKey, evmAddress }emits accountChanged
getVersion()string

Signing (no popup)

const sig = await window.enc.signSchnorr(hashHex)   // BIP-340 over a 32-byte hash → signature hex

This is how an app gets a commit signed: build the commit hash, ask the extension to signSchnorr it, and attach the signature. The key never leaves the extension.

Session keys (no popup)

const { session, sessionPriv, expires } = await window.enc.createSession(7200)  // seconds

A short-lived session key for WebSocket auth — see the session model.

ECDH & encryption (no popup)

const shared = await window.enc.ecdh(peerPubHex)                 // 32-byte hex
const key    = await window.enc.deriveKey(shared, 'enc:dm:a-b')  // HKDF → 32-byte hex
const ct     = await window.enc.encrypt(key, 'secret')          // XChaCha20-Poly1305 → base64
const pt     = await window.enc.decrypt(key, ct)

The same primitives as @enc-protocol/core, but computed inside the extension against the custodied key.

EVM transactions (popup confirm)

const { hash } = await window.enc.sendTransaction({ to, amount, memo })  // shows a confirmation popup

Events

window.enc.on('connect',        ({ pubKey, evmAddress }) => {})
window.enc.on('disconnect',     () => {})
window.enc.on('accountChanged', ({ pubKey, accountIndex }) => {})

Seed import

exportSeed() returns the 12-word mnemonic — used by an app's "import this wallet" flow so the same identity is available to the in-app SDK.

Install for development

The extension ships as a built zip. To run it locally:

  1. Build the zip (yarn build) and unzip it somewhere stable.
  2. Open chrome://extensions, enable Developer Mode, click Load unpacked, and select the extracted extension-chrome/ folder.
  3. Reload any open ENC app — the Connect-Wallet row should now show the extension as available.

The content script injects window.enc on every page, so any ENC web app can detect and connect to it.

See also