Verify every claim yourself.
Nothing on this page is a screenshot or a promise. The checks below run in your browser against the mainnet-beta cluster, and the snippet lets you repeat them without trusting this site.
No private key exists for this address
The address is a program-derived address (PDA). The runtime only accepts a PDA if it lies off the Ed25519 curve, and a private key exists only for points on the curve, so no key can exist. The address is also fully determined by three public values, which you can recompute.
- The address is off the Ed25519 curveEnter an address
If it were on the curve a private key could exist for it.
- It is derived from hashes and the programEnter an address
PDA("wallet", Keccak256(pk_seed + genesis_root + params_version), program id), recomputed from the values stored on-chain.
Verify it yourself
The same checks without this website: paste into any Node REPL, or run scripts/verify.ts from the repository.
import { PublicKey } from "@solana/web3.js";
import { keccak_256 } from "@noble/hashes/sha3";
// 1. Read the wallet's state account (its public seed values live there).
const programId = new PublicKey("13icYjQv9ZpBNcC6kdqYSkSEPY6sKQycdo8TW49MS2TS");
const [state] = PublicKey.findProgramAddressSync([Buffer.from("state"), address.toBytes()], programId);
const d = (await connection.getAccountInfo(state)).data;
const pkSeed = d.subarray(2, 34), genesisRoot = d.subarray(34, 66), v = d[1];
// 2. Recompute the address from hashes only.
const seed = keccak_256(Buffer.concat([pkSeed, genesisRoot, Buffer.from([v])]));
const [derived] = PublicKey.findProgramAddressSync([Buffer.from("wallet"), seed], programId);
console.log("matches:", derived.equals(address));
// 3. Prove no private key can exist: PDAs are off the Ed25519 curve.
console.log("on curve (a key could exist):", PublicKey.isOnCurve(address.toBytes())); // falseNothing reversible is published
This is the complete list of what Qorvex ever puts on-chain. Every item is a hash output; none is an elliptic-curve public key.
| Value | When | What it is |
|---|---|---|
genesis_root, current_root | Activation, rotation | Root of a Merkle tree of Keccak-256 hashes |
pk_seed | Activation | A Keccak-256 output derived from your seed; a public salt, not a key |
| Hash-chain values (67 × 32 bytes) | Each send | Intermediate Keccak-256 outputs of a one-time signature |
| Merkle proof (10 × 32 bytes) | Each send | Sibling hashes that tie the key to the root |
| Destination, mint, amount, expiry | Each send | The transfer itself, as on any chain |
The fee payer's Ed25519 signature on each transaction is Phantom's, and authorizes nothing but the fee.
Keys cannot be reused
The program only accepts a key whose index is at least the on-chain counter, and moves the counter past it before anything else happens. Here is the live counter for the address above.
Enter an address above.
Who can change the program
Whoever can replace the program can replace the rules. Its upgrade authority, read live from the chain:
- Upgrade authorityReading…
The account allowed to replace the program code.
Open source
- Source code and testsLink added at publication
The program, the signature library in Rust and TypeScript with shared test vectors, the threat model and the compute-unit report.