@dexterai/wallet-connect
v1.1.0
Published
Non-custodial multi-chain (Solana + EVM) wallet connect for Dexter apps — Wallet Standard picker, EIP-1193 connect, and x402 payment hooks.
Readme
What this is
A React wallet provider shared across Dexter apps (dexter-fe, x402gle). One
<WalletProvider> gives every descendant a connected Solana and/or EVM wallet,
ready-to-use x402 payment hooks, live balances, and the message-signing
primitive behind Sign-In-With-Solana / Sign-In-With-Ethereum.
The user holds their own keys. Nothing here is custodial — the package connects external wallets (Phantom, Solflare, Backpack, MetaMask, Coinbase, Rabby), it never creates or holds one.
Install
npm install @dexterai/wallet-connect @dexterai/x402 react react-domQuick start
import { WalletProvider, useWallets } from '@dexterai/wallet-connect';
function App() {
return (
<WalletProvider>
<PayButton />
</WalletProvider>
);
}
function PayButton() {
const { solanaHook, isAnyConnected } = useWallets();
return (
<button
disabled={!isAnyConnected}
onClick={() => solanaHook.fetch('https://api.example.com/paid')}
>
Pay $0.05
</button>
);
}solanaHook / baseHook are useX402Payment
instances — .fetch() handles the full 402 → sign → settle → retry cycle
against the connected wallet's own balance.
What useWallets() gives you
| Field | What it is |
|---|---|
| solanaAdapter / evmAdapter | SDK-compatible wallet adapters — signTransaction, signTypedData, signMessage |
| solanaHook / baseHook | x402 payment hooks, one per chain |
| solanaBalance / baseBalance | USDC balances |
| isSolanaConnected / isBaseConnected / isAnyConnected | connection status |
| connectEvmWallet / disconnectAll | connect / disconnect helpers |
Message signing (SIWS / SIWE)
Both adapters expose signMessage — the identity proof for wallet sign-in.
The same connected wallet that pays for x402 calls also signs the login
challenge; no separate connect step.
const { solanaAdapter, evmAdapter } = useWallets();
// Solana — Wallet Standard solana:signMessage.
// Returns the bytes the wallet actually signed (it may prefix them) and
// the Ed25519 signature. Verify the signature against `signedMessage`.
if (solanaAdapter?.canSignMessage) {
const { signedMessage, signature } =
await solanaAdapter.signMessage(new TextEncoder().encode(challenge));
}
// EVM — EIP-191 personal_sign. Returns the 0x-prefixed signature.
const signature = await evmAdapter?.signMessage({ message: challenge });Exports
WalletProvider— the context provider. Props:solanaRpcUrl,baseRpcUrl(default to Dexter's public RPC proxies).useWallets()— the consumer hook.SolanaWalletPicker— Wallet Standard picker modal, filterable by capability (signMessage/signTransaction/both).hasSolanaSignMessage/hasSolanaSignTransaction— capability checks.
License
MIT
