QRDXDocs

Wallet integration

Connect a dApp to QRDX Wallet: discovery, accounts, signing, transactions and errors.

QRDX Wallet is a standard EIP-1193 wallet with a QRDX namespace on top. Ethereum tooling works unchanged; post-quantum accounts and the native exchange use qrdx_* methods.

Find the wallet

Use EIP-6963. It works even when another wallet owns window.ethereum:

let qrdx
window.addEventListener('eip6963:announceProvider', (e) => {
  if (e.detail.info.rdns === 'org.qrdx.wallet') qrdx = e.detail.provider
})
window.dispatchEvent(new Event('eip6963:requestProvider'))

Also available: window.qrdx is always the QRDX provider (page scripts cannot overwrite it); window.ethereum is QRDX only if no other wallet took it first (window.ethereum.isQRDX).

Without the extension (the web wallet, the iPhone app), connect by QR code with QRDX Connect: you get the same provider over an encrypted relay.

Accounts

const [account] = await qrdx.request({ method: 'qrdx_requestAccounts' })
// { address: '0x…', pqAddress: '0xPQ…', pqAccountId: '0x…', pqPublicKey: '…', pqFingerprint: '…' }
const chain = await qrdx.request({ method: 'qrdx_chainInfo' })
// { id, name, chainId, isQrdx, isTestnet, nativeCurrency }
Method
eth_requestAccounts, eth_accountsthe shared 0x addresses, selected first; [] while locked or not connected
qrdx_requestAccounts, qrdx_accountseach account's address, pqAddress, pqAccountId, pqPublicKey, pqFingerprint
eth_chainId, net_version, qrdx_chainInfothe active network
wallet_switchEthereumChainnetworks in the wallet's registry only (unknown: 4902); asks the user
wallet_getPermissions, wallet_requestPermissions, wallet_revokePermissionsEIP-2255; revoking disconnects the site

Events: connect, disconnect, accountsChanged, chainChanged.

Signing

Method
personal_sign(message, address)EIP-191 with the classic key
eth_signTypedData_v4(address, typedData)EIP-712; refused if domain.chainId is not the active chain
qrdx_signPQMessage(message, address?)ML-DSA-65 over the QRDX message prefix; returns { signature, publicKey, address }. Verify with the public key (Keys and signing).
eth_signdisabled (4200): it signs arbitrary hashes and is a phishing vector

Transactions

Method
eth_sendTransaction(tx)from the classic 0x key; EIP-1559 fields are folded into a legacy gasPrice. Contract deployment from dApps is not supported.
qrdx_sendPQTransaction({ to, value, data?, gas? })from the post-quantum account, as a type-0x51 transaction; to may be any address form
qrdx_sendExchangeTransaction({ op, params, gasLimit? })any exchange operation, signed with the account's post-quantum key and next exchange nonce; returns { txHash, nonce }
wallet_watchAsset({ type: 'ERC20', options: { address, symbol, decimals } })adds a token after the user approves
Place a limit order
const { txHash } = await qrdx.request({
  method: 'qrdx_sendExchangeTransaction',
  params: [{ op: 'PLACE_ORDER', params: { pair: `QRDX:${token}`, side: 'buy', order_type: 'limit', price: '0.5', amount: '10' } }],
})
// poll exchange_getTransactionReceipt(txHash)

Every request opens an approval showing the site's real origin, the call decoded ("Buy 0.5 qBTC at 85,000 qUSDC", "Swap 1,000 qUSDC for at least 0.0117 qBTC"), the maximum fee, and warnings (unknown tokens, swaps without a minimum, token approvals).

Several operations per block. The wallet tracks the exchange nonces it has submitted that no block has included, so a dApp can, say, place an order and cancel it before the next block. A TOKEN_DEPLOY's token address is known before inclusion (0x + blake2b-160 of "<sender>:<nonce>:<symbol>"), so a dApp can create the token's pool in the same block.

Reads without connecting

These pass through to the active network's node: eth_blockNumber, eth_call, eth_estimateGas, eth_gasPrice, eth_getBalance, eth_getBlockBy*, eth_getCode, eth_getLogs, eth_getStorageAt, eth_getTransaction*, eth_getTransactionCount, eth_feeHistory, qrdx_getAccountId, qrdx_getIntrinsicGas, and the exchange_get*, exchange_quote* and perp_get* reads.

Errors

Code
4001the user rejected the request
4100not authorized: the site is not connected, or that account is not shared
4200method not supported
4900the wallet is unavailable
4902unknown chain id
-32602invalid parameters

Two accounts, one person

Each wallet account has a classic 0x address and a post-quantum 0xPQ address, which are two ledger accounts. eth_sendTransaction spends from the 0x one; qrdx_sendPQTransaction and every exchange operation from the post-quantum one (its ledger key is pqAccountId). Show users the 0xPQ address for anything they trade with.

On this page