CrossSign is a trustless cross-wallet verification layer that proves a user's wallet ownership through live cryptographic signatures and anchors verifications onchain.
CrossSign — ownership proof that doesn't need a bridge.
CrossSign is a cross-wallet verification layer. It lets an application prove that a user controls a wallet by checking a live cryptographic signature on-chain, so the result can be read by anyone instead of being asserted by a private server.
How it works. The user selects a Solana wallet (Phantom, Solflare, Backpack, OKX — any Wallet-Standard wallet) over Arbitrum/EVM wallets are used to pay for and submit the on-chain transaction. CrossSign re-reads the wallet's current account, mints a fresh challenge, and binds the chain id, verifier address, wallet public key, a single-use nonce and an expiry into one canonical message. The wallet signs it — a message signature, never a transaction, so no funds move and no approvals are granted.
On-chain verification. The signature is submitted to CrossSignVerifier, a Rust contract deployed to Arbitrum Sepolia through Stylus (Rust → WASM). It reconstructs the exact canonical message, verifies Ed25519 natively with ed25519-dalek, rejects expired challenges and replayed nonces, then mints a non-transferable badge through CrossSignBadgeRegistry. Arbitrum's Rust VM does natively what the EVM cannot — which is why this is built on Stylus.
Security model. Fresh challenge per attempt; expiry enforced in the client and in the contract; nonce burned on first use; the signature is bound to this chain, this contract, this wallet and this nonce. The live account is re-read before signing, so switching wallets mid-flow is detected rather than accepted. The backend issues nonces and formats messages only — it never performs or trusts a cryptographic decision.
Stack. Next.js 14 + TypeScript front end, ethers v6 for chain access, Rust/Stylus contracts with 28 unit tests, and a Playwright QA suite covering 67 wallet-state checks. Live: crosssign.vercel.app
<p><span><strong><em>CrossSign</em></strong></span><strong><em> </em></strong><span><strong><em>was</em></strong></span><strong><em> </em></strong><span><strong><em>built</em></strong></span><strong><em> </em></strong><span><strong><em>from</em></strong></span><strong><em> </em></strong><span><strong><em>scratch</em></strong></span><strong><em> </em></strong><span><strong><em>during</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>buildathon</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>is</em></strong></span><strong><em> </em></strong><span><strong><em>deployed</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>working</em></strong></span><strong><em> </em></strong><span><strong><em>end-to-end</em></strong></span><strong><em> </em></strong><span><strong><em>today.</em></strong></span></p><p><span><strong><em>Sep</em></strong></span><strong><em> </em></strong><span><strong><em>10–15</em></strong></span><strong><em> </em></strong><span><strong><em>—</em></strong></span><strong><em> </em></strong><span><strong><em>Foundation.</em></strong></span><strong><em> </em></strong><span><strong><em>Repository</em></strong></span><strong><em> </em></strong><span><strong><em>created</em></strong></span><strong><em> </em></strong><span><strong><em>with</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>Next.js</em></strong></span><strong><em> </em></strong><span><strong><em>14</em></strong></span><strong><em> </em></strong><span><strong><em>/</em></strong></span><strong><em> </em></strong><span><strong><em>TypeScript</em></strong></span><strong><em> </em></strong><span><strong><em>application</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>Rust</em></strong></span><strong><em> </em></strong><span><strong><em>Stylus</em></strong></span><strong><em> </em></strong><span><strong><em>contract</em></strong></span><strong><em> </em></strong><span><strong><em>workspace</em></strong></span><strong><em> </em></strong><span><strong><em>(verifier</em></strong></span><strong><em> </em></strong><span><strong><em>+</em></strong></span><strong><em> </em></strong><span><strong><em>registry).</em></strong></span><strong><em> </em></strong><span><strong><em>The</em></strong></span><strong><em> </em></strong><span><strong><em>wallet</em></strong></span><strong><em> </em></strong><span><strong><em>layer</em></strong></span><strong><em> </em></strong><span><strong><em>was</em></strong></span><strong><em> </em></strong><span><strong><em>rebuilt</em></strong></span><strong><em> </em></strong><span><strong><em>around</em></strong></span><strong><em> </em></strong><span><strong><em>open</em></strong></span><strong><em> </em></strong><span><strong><em>standards</em></strong></span><strong><em> </em></strong><span><strong><em>instead</em></strong></span><strong><em> </em></strong><span><strong><em>of</em></strong></span><strong><em> </em></strong><span><strong><em>blind</em></strong></span><strong><em> </em></strong><span><strong><em>provider</em></strong></span><strong><em> </em></strong><span><strong><em>access:</em></strong></span><strong><em> </em></strong><span><strong><em>EIP-6963</em></strong></span><strong><em> </em></strong><span><strong><em>discovery</em></strong></span><strong><em> </em></strong><span><strong><em>for</em></strong></span><strong><em> </em></strong><span><strong><em>Arbitrum</em></strong></span><strong><em> </em></strong><span><strong><em>wallets</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>Wallet</em></strong></span><strong><em> </em></strong><span><strong><em>Standard</em></strong></span><strong><em> </em></strong><span><strong><em>for</em></strong></span><strong><em> </em></strong><span><strong><em>Solana</em></strong></span><strong><em> </em></strong><span><strong><em>wallets,</em></strong></span><strong><em> </em></strong><span><strong><em>which</em></strong></span><strong><em> </em></strong><span><strong><em>removed</em></strong></span><strong><em> </em></strong><span><strong><em>hydration</em></strong></span><strong><em> </em></strong><span><strong><em>mismatches</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>multi-extension</em></strong></span><strong><em> </em></strong><span><strong><em>conflicts.</em></strong></span></p><p><span><strong><em>Sep</em></strong></span><strong><em> </em></strong><span><strong><em>16</em></strong></span><strong><em> </em></strong><span><strong><em>—</em></strong></span><strong><em> </em></strong><span><strong><em>Contracts</em></strong></span><strong><em> </em></strong><span><strong><em>deployed</em></strong></span><strong><em> </em></strong><span><strong><em>to</em></strong></span><strong><em> </em></strong><span><strong><em>Arbitrum.</em></strong></span><strong><em> </em></strong><span><strong><em>Both</em></strong></span><strong><em> </em></strong><span><strong><em>contracts</em></strong></span><strong><em> </em></strong><span><strong><em>were</em></strong></span><strong><em> </em></strong><span><strong><em>deployed</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>activated</em></strong></span><strong><em> </em></strong><span><strong><em>on</em></strong></span><strong><em> </em></strong><span><strong><em>Arbitrum</em></strong></span><strong><em> </em></strong><span><strong><em>Sepolia</em></strong></span><strong><em> </em></strong><span><strong><em>with</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">cargo-stylus</code><strong><em> </em></strong><span><strong><em>(deploy</em></strong></span><strong><em> </em></strong><span><strong><em>+</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">ProgramActivated</code><strong><em> </em></strong><span><strong><em>events</em></strong></span><strong><em> </em></strong><span><strong><em>confirmed</em></strong></span><strong><em> </em></strong><span><strong><em>on</em></strong></span><strong><em> </em></strong><span><strong><em>Arbiscan):</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>badge</em></strong></span><strong><em> </em></strong><span><strong><em>registry</em></strong></span><strong><em> </em></strong><span><strong><em>at</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">0x2862cbdc…</code><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>verifier</em></strong></span><strong><em> </em></strong><span><strong><em>at</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">0x39db2d89…</code><span><strong><em>.</em></strong></span><strong><em> </em></strong><span><strong><em>Deployment</em></strong></span><strong><em> </em></strong><span><strong><em>configuration</em></strong></span><strong><em> </em></strong><span><strong><em>was</em></strong></span><strong><em> </em></strong><span><strong><em>hardened</em></strong></span><strong><em> </em></strong><span><strong><em>(key</em></strong></span><strong><em> </em></strong><span><strong><em>handling,</em></strong></span><strong><em> </em></strong><span><strong><em>activation</em></strong></span><strong><em> </em></strong><span><strong><em>checks,</em></strong></span><strong><em> </em></strong><span><strong><em>deployment</em></strong></span><strong><em> </em></strong><span><strong><em>record)</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>failure/recovery</em></strong></span><strong><em> </em></strong><span><strong><em>paths</em></strong></span><strong><em> </em></strong><span><strong><em>of</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>verification</em></strong></span><strong><em> </em></strong><span><strong><em>flow</em></strong></span><strong><em> </em></strong><span><strong><em>were</em></strong></span><strong><em> </em></strong><span><strong><em>fixed</em></strong></span><strong><em> </em></strong><span><strong><em>so</em></strong></span><strong><em> </em></strong><span><strong><em>no</em></strong></span><strong><em> </em></strong><span><strong><em>stale</em></strong></span><strong><em> </em></strong><span><strong><em>session</em></strong></span><strong><em> </em></strong><span><strong><em>or</em></strong></span><strong><em> </em></strong><span><strong><em>wallet</em></strong></span><strong><em> </em></strong><span><strong><em>can</em></strong></span><strong><em> </em></strong><span><strong><em>be</em></strong></span><strong><em> </em></strong><span><strong><em>reused</em></strong></span><strong><em> </em></strong><span><strong><em>across</em></strong></span><strong><em> </em></strong><span><strong><em>attempts.</em></strong></span></p><p><span><strong><em>Sep</em></strong></span><strong><em> </em></strong><span><strong><em>17</em></strong></span><strong><em> </em></strong><span><strong><em>—</em></strong></span><strong><em> </em></strong><span><strong><em>Hardening</em></strong></span><strong><em> </em></strong><span><strong><em>+</em></strong></span><strong><em> </em></strong><span><strong><em>real-wallet</em></strong></span><strong><em> </em></strong><span><strong><em>fixes.</em></strong></span><strong><em> </em></strong><span><strong><em>Added</em></strong></span><strong><em> </em></strong><span><strong><em>generation-keyed</em></strong></span><strong><em> </em></strong><span><strong><em>in-flight</em></strong></span><strong><em> </em></strong><span><strong><em>protection</em></strong></span><strong><em> </em></strong><span><strong><em>(no</em></strong></span><strong><em> </em></strong><span><strong><em>stale</em></strong></span><strong><em> </em></strong><span><strong><em>or</em></strong></span><strong><em> </em></strong><span><strong><em>duplicate</em></strong></span><strong><em> </em></strong><span><strong><em>attempts),</em></strong></span><strong><em> </em></strong><span><strong><em>stricter</em></strong></span><strong><em> </em></strong><span><strong><em>signing-boundary</em></strong></span><strong><em> </em></strong><span><strong><em>validation</em></strong></span><strong><em> </em></strong><span><strong><em>(64-byte</em></strong></span><strong><em> </em></strong><span><strong><em>Ed25519,</em></strong></span><strong><em> </em></strong><span><strong><em>signature-type</em></strong></span><strong><em> </em></strong><span><strong><em>checks,</em></strong></span><strong><em> </em></strong><span><strong><em>live</em></strong></span><strong><em> </em></strong><span><strong><em>account</em></strong></span><strong><em> </em></strong><span><strong><em>re-read</em></strong></span><strong><em> </em></strong><span><strong><em>before</em></strong></span><strong><em> </em></strong><span><strong><em>signing),</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>fixed</em></strong></span><strong><em> </em></strong><span><strong><em>a</em></strong></span><strong><em> </em></strong><span><strong><em>real-browser</em></strong></span><strong><em> </em></strong><span><strong><em>issue</em></strong></span><strong><em> </em></strong><span><strong><em>found</em></strong></span><strong><em> </em></strong><span><strong><em>with</em></strong></span><strong><em> </em></strong><span><strong><em>Phantom:</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>app</em></strong></span><strong><em> </em></strong><span><strong><em>was</em></strong></span><strong><em> </em></strong><span><strong><em>calling</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">solana:signMessage</code><strong><em> </em></strong><span><strong><em>using</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>superseded</em></strong></span><strong><em> </em></strong><span><strong><em>draft</em></strong></span><strong><em> </em></strong><span><strong><em>signature</em></strong></span><strong><em> </em></strong><span><strong><em>while</em></strong></span><strong><em> </em></strong><span><strong><em>every</em></strong></span><strong><em> </em></strong><span><strong><em>current</em></strong></span><strong><em> </em></strong><span><strong><em>Wallet</em></strong></span><strong><em> </em></strong><span><strong><em>Standard</em></strong></span><strong><em> </em></strong><span><strong><em>wallet</em></strong></span><strong><em> </em></strong><span><strong><em>implements</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>current</em></strong></span><strong><em> </em></strong><span><strong><em>variadic</em></strong></span><strong><em> </em></strong><span><strong><em>form.</em></strong></span><strong><em> </em></strong><span><strong><em>The</em></strong></span><strong><em> </em></strong><span><strong><em>signing</em></strong></span><strong><em> </em></strong><span><strong><em>boundary</em></strong></span><strong><em> </em></strong><span><strong><em>is</em></strong></span><strong><em> </em></strong><span><strong><em>now</em></strong></span><strong><em> </em></strong><span><strong><em>convention-aware,</em></strong></span><strong><em> </em></strong><span><strong><em>so</em></strong></span><strong><em> </em></strong><span><strong><em>real</em></strong></span><strong><em> </em></strong><span><strong><em>Phantom</em></strong></span><strong><em> </em></strong><span><strong><em>signing</em></strong></span><strong><em> </em></strong><span><strong><em>works</em></strong></span><strong><em> </em></strong><span><strong><em>while</em></strong></span><strong><em> </em></strong><span><strong><em>legacy</em></strong></span><strong><em> </em></strong><span><strong><em>wallets</em></strong></span><strong><em> </em></strong><span><strong><em>stay</em></strong></span><strong><em> </em></strong><span><strong><em>supported.</em></strong></span></p><p><span><strong><em>QA</em></strong></span><strong><em> </em></strong><span><strong><em>+</em></strong></span><strong><em> </em></strong><span><strong><em>live</em></strong></span><strong><em> </em></strong><span><strong><em>deployment.</em></strong></span><strong><em> </em></strong><code data-inline="true" spellcheck="false">tsc</code><strong><em> </em></strong><span><strong><em>typecheck</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>production</em></strong></span><strong><em> </em></strong><span><strong><em>build</em></strong></span><strong><em> </em></strong><span><strong><em>are</em></strong></span><strong><em> </em></strong><span><strong><em>green;</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>Playwright</em></strong></span><strong><em> </em></strong><span><strong><em>wallet-state</em></strong></span><strong><em> </em></strong><span><strong><em>E2E</em></strong></span><strong><em> </em></strong><span><strong><em>suite</em></strong></span><strong><em> </em></strong><span><strong><em>grew</em></strong></span><strong><em> </em></strong><span><strong><em>from</em></strong></span><strong><em> </em></strong><span><strong><em>55</em></strong></span><strong><em> </em></strong><span><strong><em>to</em></strong></span><strong><em> </em></strong><span><strong><em>67</em></strong></span><strong><em> </em></strong><span><strong><em>checks</em></strong></span><strong><em> </em></strong><span><strong><em>(all</em></strong></span><strong><em> </em></strong><span><strong><em>passing)</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>now</em></strong></span><strong><em> </em></strong><span><strong><em>reproduces</em></strong></span><strong><em> </em></strong><span><strong><em>both</em></strong></span><strong><em> </em></strong><span><strong><em>real-browser</em></strong></span><strong><em> </em></strong><span><strong><em>bugs,</em></strong></span><strong><em> </em></strong><span><strong><em>failing</em></strong></span><strong><em> </em></strong><span><strong><em>6</em></strong></span><strong><em> </em></strong><span><strong><em>checks</em></strong></span><strong><em> </em></strong><span><strong><em>against</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>pre-fix</em></strong></span><strong><em> </em></strong><span><strong><em>build.</em></strong></span><strong><em> </em></strong><span><strong><em>28</em></strong></span><strong><em> </em></strong><span><strong><em>Rust</em></strong></span><strong><em> </em></strong><span><strong><em>unit</em></strong></span><strong><em> </em></strong><span><strong><em>tests</em></strong></span><strong><em> </em></strong><span><strong><em>cover</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>contract</em></strong></span><strong><em> </em></strong><span><strong><em>logic,</em></strong></span><strong><em> </em></strong><span><strong><em>and</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>JS↔Rust</em></strong></span><strong><em> </em></strong><span><strong><em>canonical</em></strong></span><strong><em> </em></strong><span><strong><em>message</em></strong></span><strong><em> </em></strong><span><strong><em>is</em></strong></span><strong><em> </em></strong><span><strong><em>checked</em></strong></span><strong><em> </em></strong><span><strong><em>byte-for-byte</em></strong></span><strong><em> </em></strong><span><strong><em>by</em></strong></span><strong><em> </em></strong><span><strong><em>script.</em></strong></span><strong><em> </em></strong><span><strong><em>The</em></strong></span><strong><em> </em></strong><span><strong><em>app</em></strong></span><strong><em> </em></strong><span><strong><em>is</em></strong></span><strong><em> </em></strong><span><strong><em>live</em></strong></span><strong><em> </em></strong><span><strong><em>at</em></strong></span><strong><em> </em></strong><a href="https://crosssign.vercel.app"><span><strong><em><u>https://crosssign.vercel.app</u></em></strong></span></a><span><strong><em>,</em></strong></span><strong><em> </em></strong><span><strong><em>connected</em></strong></span><strong><em> </em></strong><span><strong><em>to</em></strong></span><strong><em> </em></strong><span><strong><em>the</em></strong></span><strong><em> </em></strong><span><strong><em>deployed</em></strong></span><strong><em> </em></strong><span><strong><em>contracts</em></strong></span></p>
<p><span style="color: rgb(199, 194, 188)"><strong><em>Not raising. CrossSign is a self-funded buildathon project , no external funding, no investors, and no token. Any future funding would be used to harden the contracts (external review, gas benchmarking) and to open the verification API to other applications.</em></strong></span></p>