The app is only end to end encrypted if you trust the server to give you the right keys from the beginning (it's E2EE meets TOFU): since there is no way to verify what information (the "sigchains") the server sent to your device (no safety number like in signal, encryption key like in Telegram, fingerprint like in Wire, or whatever you call it), you have to trust the server. The app does verify that nothing changes, so the server has to consistently lie to the device, and to app clients
only because a command line client could verify the keys. Then again, since very, very few people do or can do this verification, and since the verification tutorial in the documentation is relatively complex and broken (an api call doesn't return a signatures field the tutorial relies on) and nobody seems to have noticed, it's probably a safe bet for an attacker that compromised the server to just MITM all devices of some users without being noticed.
Note that the blockchain magic does nothing because the app doesn't verify it, and if it did, it would have to be a normal bitcoin client, which would take lots of traffic, storage (even with SPV, you need all the block headers), and shifts the trust to a lot of third parties instead of one (so that's quite trustworthy and great for my grandma that doesn't verify keys, but personally I'd prefer to just check a key in favor of running a bitcoin client on my phone). But that's not implemented yet so this point is moot anyway. And if I'm not mistaken, one needs to compute the merkle tree completely, that is, hash all sigchain of all Keybase users (imagine they become popular and you have to download a literal billion sigchains and hash them all together on a phone) to match it against the final value you get from the blockchain.
Finally, someone brought up verifying keys with another device. I'm not sure if that works. It might, depending on how the key exchange works and if it forces you to verify something in the app. If you don't, I mean, in the situation that the server spoofs your sigchain (MITM) to your friends, it can do that between your devices as well and report whatever value it used for the merkle tree to your command line client so everything checks out.
So it's not completely broken, but trusting the server on first use is m a lesser guarantee than all other E2EE software, and the fix is really simple so I don't get why they don't implement it (note that I don't mean to hint that they're indeed MITMing and that's why they don't let people verify it; I genuinely don't understand why not allow people to do this, I see no reason). My best guess is that they either didn't think of the scenario themselves (and NCC also missed it, which makes sense since they verified the crypto and code and not how a normal user would actually verify this in the UI) or they don't want to admit now that it depended on closed source servers being trusted all along.
Relevant question: https://security.stackexchange.com/questions/222055/how-can-...