Search projects, hackathons, sponsors and tech

    ← All projects

    Krtek Wallet + 2FA

    Easy to use wallet with 2FA that feels like web2

    About

    The problem it solves Demo Video: https://drive.google.com/drive/folders/1sm5W6mXupJr4u48jPRc-gyBWgD5eg A self-custodial EVM wallet for non-crypto-natives. **No seed phrase, ever.** Signing in with ENS and password derives your owner key in the browser (Argon2id), funds live in an ERC-4337 smart account, and a custom paymaster sponsors gas so users never need ETH to make their first move. ## What's built ### 1. Password-only login → on-chain smart account Argon2id over `(password, sha256("krtek.wallet.v1.password-key:" + handle))` deterministically derives a secp256k1 owner key in the browser. The owner key lives only in tab memory; nothing secret touches localStorage. The same password+handle on any device yields the same wallet — a real ERC-4337 v0.7 SCA at a CREATE2 address. See `web/src/lib/password-key.ts`, `PASSWORD_LOGIN.md`. ### 2. Custom verifying paymaster (gasless onboarding) A Bun service signs `paymasterAndData` for every UserOp; the on-chain `KrtekPaymaster` verifies the signature in `validatePaymasterUserOp`. Works on any chain you give it addresses for — anvil, Sepolia, real L2s. Users never need ETH to make their first move. See `paymaster-server/`. ### 3. M-of-N social recovery The SCA carries a `setGuardians(address[], threshold)` slot. Recovery is a single `recoverOwner(newOwner, deadline, signatures[])` call that verifies M unique guardian sigs against a per-account replay nonce. Lose your password, collect signatures from your friends, rotate to a fresh owner key — same SCA address. See `contracts/src/KrtekSCA.sol`, [`web/src/routes/Recover.tsx`](./web/src/routes/Recover.tsx). ### 4. Phone 2FA via WebSocket relay The SCA's `validateUserOp` accepts a 130-byte signature: `ownerSig` (EIP-191) `||` `phoneSig` (raw secp over the userOpHash). With `lockToPhone=true`, every UserOp must be co-signed by a paired phone. Pairing flow lives in Settings → Phone 2FA; the existing `mobile/` companion handles the user-side approval UX. See `web/src/lib/relay/`, `mobile/`. ### 5. Sourcify APIv2 deep integration Built specifically for the Sourcify bounty: - **Provenance Card** — animated visualization of the source-files → metadata.json → IPFS CID → CBOR auxdata → on-chain bytecode chain - **Transformations diff** — renders the `transformations[]` array as bullets *and* annotated hex showing constructor args / libraries / immutables / cborAuxdata regions in the deployed bytecode - **Multi-chain trust strip** — `/v2/contract/all-chains/{address}` showing where else the same code is verified - **In-browser re-verification** — applies `transformations[]` to `recompiledBytecode` locally, decodes the CBOR auxdata, attempts to reproduce the IPFS CID — proves the verification mathematically without trusting the public Sourcify server - **Source files drawer** — every source file with a Solidity highlighter, the file containing the called function highlighted Uses APIv2 (the legacy `/files/...` endpoints went into brownouts in May 2026), the new `exact_match` / `match` vocabulary, and `proxyResolution` to follow proxies natively. See `web/src/lib/sourcify.ts`, `web/src/lib/sourcify-verify.ts`, `web/src/components/wallet/{ProvenanceCard,TransformationsView,SourceFilesDrawer,MultiChainStrip}.tsx`. ### 6. Multi-profile + auto-resume Multiple wallets per device under different handles. Pairing state and SCA caches persist per profile; logging in re-attaches the relay session transparently. See `web/src/lib/profiles.ts`. ### 7. USB Armory MK II — hardware-attested 2FA Same SCA cosigner slot as the phone, different transport: an i.MX6ULL Trusted Applet (Rust, no_std, ARM TrustZone Secure World) holds a secp256k1 key derived from the chip's DCP hardware-attestation primitive (`sk = sha256("krtek-signer-v1" || RPC.Attest)`). The applet only exposes `GetPubkey`, `GetAddress`, `Approve(digest)` and `Health` — it has no `ExportSecret` method, so the key never crosses the syscall boundary back to Normal World. Pulling the SD card and cloning storage doesn't yield the key; the DCP secret is silicon-locked. End-to-end: web app → `armory-bridge/` (Bun + Hono on `:4141`) → `nc 10.0.0.1:4000` (USB-CDC-ECM bridge) → applet → 65-byte recoverable ECDSA signature → web concatenates `ownerSig || armorySig` into the same 130-byte UserOp signature shape the phone path produces. The SCA verifies with one `ECDSA.recover` call per signature; it doesn't care whether the cosigner is a phone or an Armory. `web/src/lib/send.ts` runs `decideCosigner(sender)`: if the Armory's deterministic address matches the on-chain `phoneSigner`, sign via the Armory; else if the relay-paired phone matches, sign via the phone; else owner-only (which the contract refuses if `lockToPhone=true`). The applet itself lives in the gitignored `gotee_starter/` SDK fork; the host-side wiring is `armory-bridge/`, `web/src/lib/armory/`, `web/src/components/wallet/ArmoryTfaCard.tsx`. ### 8. Cosmic Backup — cTRNG-seeded self-recovery phrase A 24-word BIP-39 phrase

    How it's made

    Challenges we ran into We had some issues setting up armory hardware device from space computer but we were able to make it work on one of the laptops.