* refactor(bootstrap): add BootstrapShim
* feat(security): [#209] generate public/private keys
* refactor(encryption): move encryption utils to a service
* feat(encryption): [wip] implement convertCryptoKeyToString
* fix(user-settings): serialize crypto keys to strings
* feat(user-settings): deserialize user settings from IndexedDB
* feat(user-settings): upgrade persisted settings on boot
* feat(user-settings): automatically migrate persisted user settings
* refactor(encryption): simplify CryptoKey stringification
* refactor(encryption): DRY up EncryptionService
* feat(verification): send public key to new peers
* refactor(encryption): use class instance
* refactor(serialization): use class instance
* refactor(verification): [wip] create usePeerVerification hook
* feat(verification): encrypt verification token
* feat(verification): send encrypted token to peer
* feat(verification): verify peer
* refactor(verification): use enum for verification state
* feat(verification): expire verification requests
* fix(updatePeer): update with fresh state data
* feat(verification): display verification state
* refactor(usePeerVerification): store verification timer in Peer
* feat(verification): present tooltips explaining verification state
* feat(ui): show full page loading indicator
* feat(init): present bootup failure reasons
* refactor(init): move init to its own file
* feat(verification): show errors upon verification failure
* refactor(verification): move workaround to usePeerVerification
* feat(verification): present peer public keys
* refactor(verification): move peer public key rendering to its own component
* refactor(verification): only pass publicKey into renderer
* feat(verification): show user's own public key
* refactor(naming): rename Username to UserInfo
* refactor(loading): encapsulate height styling
* feat(verification): improve user messaging
* refactor(style): improve formatting and variable names
* feat(verification): add user info tooltip
* docs(verification): explain verification
* feat(sdk): render iframe in chat-room component
* fix(ci): install optional dependencies
* feat(sdk): allow subset of attributes
* feat(sdk): accept root-domain attribute
* feat(sdk): accept custom room name or use sane default
* feat(sdk): set allowed features
* feat(sdk): add sdk instructions to embed code dialog
* fix(sdk): use dynamic rootUrl
* fix(sdk): use static defaultRoot
* feat(sdk): send config from SDK to chat
* fix(sdk): expire poller
* fix(sdk): pass parent domain to iframe via query param
* refactor(sdk): type message event data
* feat(sdk): send user id to chat frame
* feat(sdk): handle some attribute updates
* chore(package): add build:sdk:watch script
* refactor(sdk): move more code to updateIframeAttributes
* feat(sdk): support changing rooms
* feat(sdk): support more user settings
* docs(sdk): add SDK section to README
* feat(sdk): render root-url in embed code if necessary
* refactor(sdk): use map for chat room attributes
* fix(sdk): unbind event listener when chat-room is disconnected
* fix(sdk): properly tear down receipt listener
* fix(sdk): send config when frame reloads
* feat(sdk): listen for config updates
* feat(sdk): request config from sdk instead of sending it repeatedly
* refactor(sdk): use type guard for config message
* fix(sdk): use settings from SDK when there is no preexisting persisted data
* fix(sdk): observe all iframe attributes
* refactor(sdk): simplify bootup logic
* feat(sdk): improve embed code display