Connect a Wallet
The provider object
Every Valdium-compatible browser wallet injects a provider object at window.valdium. It mirrors the shape the JSON-RPC provider standard established for Ethereum, deliberately, so dapp authors can port over with surface-level changes:
if (typeof window.valdium === 'undefined') {
// wallet not installed
throw new Error('No Valdium wallet detected');
}
const provider = window.valdium;
const accounts = await provider.request({
method: 'eth_requestAccounts'
});
const address = accounts[0];The method namespace is val_*, distinct from Ethereum's wallet-adapter methods. This is not cosmetic — it lets a dapp that touches both the Ethereum ERC-20 token and the Valdium L1 avoid sending an ECDSA-shaped request into a Dilithium signer, which would fail in a confusing way. If you have integrated MetaMask or the EVM wallet-adapter before, the request/approve shape will feel familiar; the methods are different.
Core RPC methods
| Method | Returns | What it does |
|---|---|---|
eth_requestAccounts | address[] | Prompts the user to pick an account and grants the dapp read access |
eth_accounts | address[] | Returns already-permitted accounts; never prompts |
eth_chainId | 0x539 | Returns the active chain ID (testnet = 1337) |
eth_getBalance | string | VLD balance of an address in wei (10⁻¹⁸ VLD) |
eth_signTransaction | { raw, hash } | Prompts user to sign and returns the encoded tx |
eth_sendTransaction | hash | Signs and broadcasts in one step |
eth_call | string | Eth-style read call against a contract — no signing |
personal_sign | string | Sign arbitrary bytes (Dilithium3 over a domain-separated digest) |
All addresses are 20-byte hex, 0x-prefixed and lowercase. All hashes and signatures are 0x-prefixed lowercase. Value parameters are decimal strings or 0x-prefixed hex, never floats.
Connect button — minimum viable code
The smallest connect flow a dapp can ship:
const btn = document.querySelector('#connect');
btn.addEventListener('click', async () => {
if (!window.valdium) {
window.open('https://valdium.xyz/launch-list', '_blank');
return;
}
try {
const [account] = await window.valdium.request({
method: 'eth_requestAccounts'
});
btn.textContent = account.slice(0, 6) + '…' + account.slice(-4);
} catch (err) {
if (err.code === 4001) return; // user rejected
console.error(err);
}
});Error code 4001 is "user rejected" and should always be handled as a silent no-op — never as an error toast. Anything else is a real failure and should surface to the user.
Reacting to account and chain changes
The provider emits two events that a long-lived dapp must listen to:
window.valdium.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
// user disconnected the dapp
} else {
// selected account changed — reload state
}
});
window.valdium.on('chainChanged', (chainId) => {
// chainId is a hex string like '0x539'
// dapps generally do a full reload here
window.location.reload();
});If the dapp keeps server-side state (positions, claimed airdrops) tied to an address, an accountsChanged event is your signal to refetch — don't keep showing the previous account's balance.
Sending a transaction
The fast path is eth_sendTransaction — sign and broadcast in one call:
const hash = await window.valdium.request({
method: 'eth_sendTransaction',
params: [{
from: address,
to: 'Va1d1umRecipientAdd7essBase58Examp1eXXXXXX',
value: '1000000000000000000', // 1 VLD in wei (18 decimals)
memo: '',
}]
});The wallet will fill in nonce, gas, and chainId on your behalf and show the user the full prompt. If you have specific gas requirements, pass gasLimit and maxFeePerGas explicitly — see the fee market doc for the model.
Library shims
You don't have to write request blocks by hand. Two integrations are first-class:
- ethers.js / viem. Wrap
window.valdiumwith the Valdium provider shim from@valdium/sdkand the standardBrowserProvider+Signershapes work end-to-end. - @valdium/sdk. The native client. Provides
ValdiumWallet.fromProvider(window.valdium)as the canonical entry point.
import { ValdiumProvider } from '@valdium/sdk';
const vp = new ValdiumProvider(window.valdium);
const signer = await vp.getSigner();
const tx = await signer.sendTransaction({ to, value });
await tx.wait();Detecting which wallet is installed
The provider object exposes a walletMeta read-only property that names the wallet vendor and version. This is useful when the dapp wants to render different help text for, say, the standalone Valdium extension versus a MetaMask connection:
const meta = window.valdium.walletMeta;
// { name: 'Valdium Wallet', version: '0.5.14', via: 'extension' }
// or 'phantom'
// or 'mobile'