A self-custodial browser wallet for Bitcoin, Ethereum & Solana — with a standards-based dApp provider that works on any website. Add “Connect Wonder Wallet” in a few lines, or get it for free through the wallet standards.
@solana/wallet-adapter). The Bitcoin API below is the part worth wiring up.window.wonderWalletAn EIP-1193-style provider (mirrors the UniSat/OKX shape, so it’s familiar). Detect it, connect, then request signatures — every signature is approved by the user in the extension.
function onWonderWallet(cb){
if (window.wonderWallet) return cb(window.wonderWallet);
window.addEventListener('wonder-wallet#initialized', () => cb(window.wonderWallet), { once:true });
}
onWonderWallet(async (ww) => {
// Returns { accounts:[address], proof:{ address, message, signature, scheme:'BIP-322' } }
const { accounts, proof } = await ww.requestAccounts();
// proof = Sign-In With Bitcoin: verify server-side (see below) for one-round-trip auth.
});
await ww.getAccounts(); // [] until connected
await ww.getPublicKey(); // hex
await ww.getBalances(); // { confirmed, unconfirmed, total } (sats)
await ww.signMessage('hello'); // BIP-322 signature
await ww.signPsbt(psbtHex, { // sign ONLY the user's inputs
toSignInputs:[{ index:0 }], // optional; defaults to all of the user's inputs
autoFinalized:false, // false → returns signed PSBT; true → finalized tx hex
});
await ww.broadcastTransaction(txHex); // { txid }
await ww.disconnect();
ww.on('accountsChanged', a => {});
ww.on('disconnect', () => {});
At connect, the wallet auto-signs a message it generated: Domain, Nonce, Issued At. Verify (1) the Domain is your origin, (2) Issued At is within 5 minutes, and (3) the BIP-322 signature is valid for the returned address. One round trip, no second prompt.
With wagmi / RainbowKit / viem / web3modal you do nothing — Wonder Wallet shows up in the wallet list. To wire it by hand, listen for the EIP-6963 announcement:
window.addEventListener('eip6963:announceProvider', (e) => {
if (e.detail.info.rdns === 'com.wonderwallet') {
const provider = e.detail.provider; // standard EIP-1193
provider.request({ method:'eth_requestAccounts' });
}
});
window.dispatchEvent(new Event('eip6963:requestProvider'));
await p.request({ method:'eth_requestAccounts' }); // [address] — prompts to connect
await p.request({ method:'eth_accounts' }); // [] until connected
await p.request({ method:'eth_chainId' }); // '0x1'
await p.request({ method:'personal_sign', params:[msgHex, address] });
await p.request({ method:'eth_signTypedData_v4', params:[address, typedDataJSON] }); // EIP-712
await p.request({ method:'eth_sendTransaction', params:[{ to, value, data }] }); // signs, broadcasts → tx hash
p.on('accountsChanged', a => {});
p.on('chainChanged', c => {});
Use @solana/wallet-adapter (or any Wallet-Standard kit) and “Wonder Wallet” appears in the wallet list automatically — no code needed. Supported features:
standard:connect / standard:disconnect / standard:events solana:signMessage // sign arbitrary bytes solana:signTransaction // sign, returns the signed tx solana:signAndSendTransaction // sign + submit → signature
Questions or want to be listed as a supported dApp? Open an issue on GitHub or say hi in the Telegram.