Skip to content

Migrating to 0.2.0

Snazzah edited this page Nov 2, 2026 · 2 revisions

Version 0.2.0 is all about bringing davey up to parity with libdave and fixing a lot of bugs. You should find this version a lot more secure and a lot more stable, especially with handling packets during transitions. Theres a handful of breaking changes though.

  • process_welcome now allows for a list of recognized user IDs, which INCLUDES your own ID! (because you are apart of the group) You should've already been having your own set of IDs from the websocket, but now processing welcomes use it to reject any rogue IDs in the welcome.
this.daveSession.processWelcome(m.subarray(5), [...this.#clientsConnected, this.#userID]);
  • After processing commits/welcomes (and also whenever Discord signals it with DAVE_PREPARE_TRANSITION), you must prepare the transition in the session with prepare_transition, which now handles keys properly internally. The arguments are the transition ID and the current protocol version
this.daveSession.prepareTransition(transitionID, this.daveSession.protocolVersion);
  • Commits can now be ignored. process_commit now returns a boolean if we should be prepared to transition or if it will be ignored. (Usually libdave just gives an empty commit and the voice gateway rejects it silently anyway)
if(!this.daveSession.processCommit(m.subarray(5))) {
  this.emit("debug", `MLS commit ignored (transition ID: ${transitionID})`);
  break;
}
this.daveSession.prepareTransition(transitionID, this.daveSession.protocolVersion);
  • Packets being sent can now be dropped. Check for can_encrypt to see if we can encrypt packets, so we don't end up sending unencrypted things. This also stops sending data to uninitialized MLS groups (i.e. a voice channel with just the bot in it) so hey, less useless traffic!
let frame = unencryptedFrame;
if(this.#daveReady && !unencryptedFrame.equals(SILENCE_FRAME)) {
  // After a welcome, we dont yet have a key until the transition is executed,
  // so we stop sending frames until we have a key to encrypt with
  if(!this.daveSession.canEncrypt) {
    return;
  }
  frame = this.daveSession.encryptOpus(unencryptedFrame);
}
  • When upgrading to an E2EE session, enable passthrough mode on re-init., this will be turned off automatically once the group is established.
// When upgrading, unencrypted packets are still sent until the transition is executed
if(this.#daveDowngraded) {
  this.daveSession.setPassthroughMode(true);
}
  • Pass execute_transition to the session, except when the ID is 0
// ID 0 already gets executed by davey
if(transitionID !== 0) {
  try {
    this.daveSession?.executeTransition(transitionID);
  } catch(e) {
    this.emit("warn", `Failed to execute DAVE transition: ${e}`);
  }
}

Clone this wiki locally