@ermis-network/ermis-chat-sdk 1.0.9 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +330 -0
  2. package/bin/init-call.js +9 -0
  3. package/dist/encryption/index.browser.cjs +13045 -0
  4. package/dist/encryption/index.browser.cjs.map +1 -0
  5. package/dist/encryption/index.browser.mjs +12959 -0
  6. package/dist/encryption/index.browser.mjs.map +1 -0
  7. package/dist/encryption/index.cjs +13045 -0
  8. package/dist/encryption/index.cjs.map +1 -0
  9. package/dist/encryption/index.d.mts +3 -0
  10. package/dist/encryption/index.d.ts +3 -0
  11. package/dist/encryption/index.mjs +12959 -0
  12. package/dist/encryption/index.mjs.map +1 -0
  13. package/dist/index-CcvHIY5q.d.mts +4988 -0
  14. package/dist/index-CcvHIY5q.d.ts +4988 -0
  15. package/dist/index.browser.cjs +20399 -6823
  16. package/dist/index.browser.cjs.map +1 -1
  17. package/dist/index.browser.full-bundle.min.js +20 -18
  18. package/dist/index.browser.full-bundle.min.js.map +1 -1
  19. package/dist/index.browser.mjs +20315 -6790
  20. package/dist/index.browser.mjs.map +1 -1
  21. package/dist/index.cjs +20400 -6824
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.mts +167 -1356
  24. package/dist/index.d.ts +167 -1356
  25. package/dist/index.mjs +20312 -6787
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/wasm_worker.worker.mjs +1600 -0
  28. package/dist/wasm_worker.worker.mjs.map +1 -0
  29. package/package.json +22 -7
  30. package/public/e2ee-media-stream-worker.js +627 -0
  31. package/public/ermis_call_node_wasm_bg.wasm +0 -0
  32. package/public/openmls_wasm_bg.wasm +0 -0
  33. package/src/attachment_utils.ts +0 -148
  34. package/src/auth.ts +0 -352
  35. package/src/channel.ts +0 -1806
  36. package/src/channel_state.ts +0 -607
  37. package/src/client.ts +0 -1617
  38. package/src/client_state.ts +0 -55
  39. package/src/connection.ts +0 -587
  40. package/src/ermis_call_node.ts +0 -978
  41. package/src/errors.ts +0 -60
  42. package/src/events.ts +0 -46
  43. package/src/hevc_decoder_config.ts +0 -305
  44. package/src/index.ts +0 -16
  45. package/src/media_stream_receiver.ts +0 -525
  46. package/src/media_stream_sender.ts +0 -400
  47. package/src/shims/empty.ts +0 -1
  48. package/src/signal_message.ts +0 -146
  49. package/src/system_message.ts +0 -117
  50. package/src/token_manager.ts +0 -48
  51. package/src/types.ts +0 -581
  52. package/src/utils.ts +0 -534
  53. package/src/wasm/ermis_call_node_wasm.d.ts +0 -154
  54. package/src/wasm/ermis_call_node_wasm.js +0 -1498
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/encryption/wasm/openmls_wasm.js","../../src/encryption/index.ts","../../src/encryption/encoding.ts","../../src/encryption/api.ts","../../src/utils.ts","../../src/logger.ts","../../src/encryption/storage.ts","../../src/encryption/aad.ts","../../src/encryption/sha256.ts","../../src/encryption/attachment_crypto_provider.ts","../../src/encryption/attachments.ts","../../src/encryption/e2ee_media_stream.ts","../../src/encryption/manager.ts","../../src/encryption/openmls.ts","../../src/encryption/e2ee_media_mp4_probe.ts","../../src/encryption/e2ee_media_stream_planner.ts"],"sourcesContent":["let wasm;\n\nconst cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );\n\nif (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };\n\nlet cachedUint8ArrayMemory0 = null;\n\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nfunction addToExternrefTable0(obj) {\n const idx = wasm.__externref_table_alloc();\n wasm.__wbindgen_export_2.set(idx, obj);\n return idx;\n}\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n const idx = addToExternrefTable0(e);\n wasm.__wbindgen_exn_store(idx);\n }\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nconst cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );\n\nconst encodeString = (typeof cachedTextEncoder.encodeInto === 'function'\n ? function (arg, view) {\n return cachedTextEncoder.encodeInto(arg, view);\n}\n : function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n});\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = encodeString(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nlet cachedDataViewMemory0 = null;\n\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction debugString(val) {\n // primitive types\n const type = typeof val;\n if (type == 'number' || type == 'boolean' || val == null) {\n return `${val}`;\n }\n if (type == 'string') {\n return `\"${val}\"`;\n }\n if (type == 'symbol') {\n const description = val.description;\n if (description == null) {\n return 'Symbol';\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == 'function') {\n const name = val.name;\n if (typeof name == 'string' && name.length > 0) {\n return `Function(${name})`;\n } else {\n return 'Function';\n }\n }\n // objects\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = '[';\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for(let i = 1; i < length; i++) {\n debug += ', ' + debugString(val[i]);\n }\n debug += ']';\n return debug;\n }\n // Test for built-in\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n // Failed to match the standard '[object ClassName]'\n return toString.call(val);\n }\n if (className == 'Object') {\n // we're a user defined class or Object\n // JSON.stringify avoids problems with cycles, and is generally much\n // easier than looping through ownProperties of `val`.\n try {\n return 'Object(' + JSON.stringify(val) + ')';\n } catch (_) {\n return 'Object';\n }\n }\n // errors\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\\n${val.stack}`;\n }\n // TODO we could test for more things here, like `Set`s and `Map`s.\n return className;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nfunction _assertClass(instance, klass) {\n if (!(instance instanceof klass)) {\n throw new Error(`expected instance of ${klass.name}`);\n }\n}\n\nfunction takeFromExternrefTable0(idx) {\n const value = wasm.__wbindgen_export_2.get(idx);\n wasm.__externref_table_dealloc(idx);\n return value;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1, 1) >>> 0;\n getUint8ArrayMemory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\n\nfunction getArrayJsValueFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n const mem = getDataViewMemory0();\n const result = [];\n for (let i = ptr; i < ptr + 4 * len; i += 4) {\n result.push(wasm.__wbindgen_export_2.get(mem.getUint32(i, true)));\n }\n wasm.__externref_drop_slice(ptr, len);\n return result;\n}\n\nfunction passArrayJsValueToWasm0(array, malloc) {\n const ptr = malloc(array.length * 4, 4) >>> 0;\n for (let i = 0; i < array.length; i++) {\n const add = addToExternrefTable0(array[i]);\n getDataViewMemory0().setUint32(ptr + 4 * i, add, true);\n }\n WASM_VECTOR_LEN = array.length;\n return ptr;\n}\n\nlet cachedUint32ArrayMemory0 = null;\n\nfunction getUint32ArrayMemory0() {\n if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {\n cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);\n }\n return cachedUint32ArrayMemory0;\n}\n\nfunction passArray32ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 4, 4) >>> 0;\n getUint32ArrayMemory0().set(arg, ptr / 4);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\n/**\n * Validate raw key package bytes without constructing a KeyPackage object.\n *\n * Performs full validation: TLS deserialization, signature verification,\n * protocol version check, lifetime check, init_key ≠ encryption_key.\n *\n * # Arguments\n * * `bytes` - TLS-serialized KeyPackage bytes (from server API)\n *\n * # Returns\n * `true` if the KeyPackage is valid, `false` otherwise.\n *\n * # Example\n * ```javascript\n * const isValid = validate_key_package_bytes(kpBytes);\n * if (!isValid) globalThis.__ermisSdkLog?.('warn', \"Invalid KeyPackage!\");\n * ```\n * @param {Uint8Array} bytes\n * @returns {boolean}\n */\nexport function validate_key_package_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.validate_key_package_bytes(ptr0, len0);\n return ret !== 0;\n}\n\n/**\n * @param {Provider} provider\n * @returns {RecoveryKeypair}\n */\nexport function generate_recovery_keypair(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.generate_recovery_keypair(provider.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return RecoveryKeypair.__wrap(ret[0]);\n}\n\n/**\n * @param {Provider} provider\n * @param {Uint8Array} adk\n * @param {Uint8Array} ciphertext\n * @param {Uint8Array} nonce\n * @param {Uint8Array} aead_aad\n * @returns {Uint8Array}\n */\nexport function decrypt_archive_blob(provider, adk, ciphertext, nonce, aead_aad) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(adk, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(ciphertext, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passArray8ToWasm0(nonce, wasm.__wbindgen_malloc);\n const len2 = WASM_VECTOR_LEN;\n const ptr3 = passArray8ToWasm0(aead_aad, wasm.__wbindgen_malloc);\n const len3 = WASM_VECTOR_LEN;\n const ret = wasm.decrypt_archive_blob(provider.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v5;\n}\n\n/**\n * @param {Provider} provider\n * @param {Uint8Array} archive_bytes\n * @param {ArchiveBlobAad} aad\n * @returns {EncryptedArchiveBlob}\n */\nexport function encrypt_archive_blob(provider, archive_bytes, aad) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(archive_bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n _assertClass(aad, ArchiveBlobAad);\n const ret = wasm.encrypt_archive_blob(provider.__wbg_ptr, ptr0, len0, aad.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return EncryptedArchiveBlob.__wrap(ret[0]);\n}\n\n/**\n * @param {Provider} provider\n * @param {Uint8Array} recovery_private_key\n * @param {Uint8Array} kem_output\n * @param {Uint8Array} ciphertext\n * @param {Uint8Array} hpke_info\n * @returns {Uint8Array}\n */\nexport function unwrap_archive_data_key_from_parts(provider, recovery_private_key, kem_output, ciphertext, hpke_info) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(recovery_private_key, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(kem_output, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passArray8ToWasm0(ciphertext, wasm.__wbindgen_malloc);\n const len2 = WASM_VECTOR_LEN;\n const ptr3 = passArray8ToWasm0(hpke_info, wasm.__wbindgen_malloc);\n const len3 = WASM_VECTOR_LEN;\n const ret = wasm.unwrap_archive_data_key_from_parts(provider.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v5 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v5;\n}\n\n/**\n * @param {Provider} provider\n * @param {Uint8Array} adk\n * @param {Uint8Array} recipient_recovery_public_key\n * @param {ArchiveKeyWrapInfo} info\n * @returns {HpkeWrappedArchiveDataKey}\n */\nexport function wrap_archive_data_key(provider, adk, recipient_recovery_public_key, info) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(adk, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(recipient_recovery_public_key, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n _assertClass(info, ArchiveKeyWrapInfo);\n const ret = wasm.wrap_archive_data_key(provider.__wbg_ptr, ptr0, len0, ptr1, len1, info.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return HpkeWrappedArchiveDataKey.__wrap(ret[0]);\n}\n\n/**\n * @param {Provider} provider\n * @param {string} pin\n * @param {Uint8Array} private_key\n * @param {Uint8Array} public_key\n * @param {string} key_id\n * @param {number} ciphersuite\n * @param {number} iterations\n * @returns {WrappedRecoveryKey}\n */\nexport function wrap_recovery_private_key(provider, pin, private_key, public_key, key_id, ciphersuite, iterations) {\n _assertClass(provider, Provider);\n const ptr0 = passStringToWasm0(pin, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passArray8ToWasm0(public_key, wasm.__wbindgen_malloc);\n const len2 = WASM_VECTOR_LEN;\n const ptr3 = passStringToWasm0(key_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len3 = WASM_VECTOR_LEN;\n const ret = wasm.wrap_recovery_private_key(provider.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ciphersuite, iterations);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return WrappedRecoveryKey.__wrap(ret[0]);\n}\n\n/**\n * @param {Provider} provider\n * @param {Uint8Array} recovery_private_key\n * @param {HpkeWrappedArchiveDataKey} wrapped\n * @returns {Uint8Array}\n */\nexport function unwrap_archive_data_key(provider, recovery_private_key, wrapped) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(recovery_private_key, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n _assertClass(wrapped, HpkeWrappedArchiveDataKey);\n const ret = wasm.unwrap_archive_data_key(provider.__wbg_ptr, ptr0, len0, wrapped.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v2;\n}\n\n/**\n * @param {Provider} provider\n * @param {string} pin\n * @param {WrappedRecoveryKey} wrapped\n * @returns {Uint8Array}\n */\nexport function unwrap_recovery_private_key(provider, pin, wrapped) {\n _assertClass(provider, Provider);\n const ptr0 = passStringToWasm0(pin, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n _assertClass(wrapped, WrappedRecoveryKey);\n const ret = wasm.unwrap_recovery_private_key(provider.__wbg_ptr, ptr0, len0, wrapped.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v2;\n}\n\n/**\n * Test function to verify the module is working\n */\nexport function greet() {\n wasm.greet();\n}\n\n/**\n * Initialize the WASM module\n *\n * Call this once at startup to set up panic hooks for better error messages.\n */\nexport function init() {\n wasm.init();\n}\n\n/**\n * Compute the deterministic channel_id for E2EE Messaging (DM) channels.\n *\n * Replicates the server-side `hash_channel_id()` in bellboy/src/util/check.rs.\n * Only needed for E2EE DM creation — standard (non-E2EE) Messaging channels\n * have their channel_id computed server-side.\n *\n * Algorithm:\n * 1. Sort user_ids alphabetically\n * 2. Concatenate (no separator)\n * 3. SHA-256 → hex string\n * 4. Truncate to 36 chars\n * 5. Return \"{project_id}:{hash36}\"\n *\n * # Example\n * ```javascript\n * const channelId = hash_channel_id(\"proj-uuid\", [\"alice\", \"bob\"]);\n * const cid = `messaging:${channelId}`;\n * const group = Group.create_with_cid(provider, identity, cid);\n * ```\n * @param {string} project_id\n * @param {string[]} user_ids\n * @returns {string}\n */\nexport function hash_channel_id(project_id, user_ids) {\n let deferred3_0;\n let deferred3_1;\n try {\n const ptr0 = passStringToWasm0(project_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArrayJsValueToWasm0(user_ids, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.hash_channel_id(ptr0, len0, ptr1, len1);\n deferred3_0 = ret[0];\n deferred3_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);\n }\n}\n\n/**\n * Decrypt and verify an MLS private message using a V2 archive + snapshot.\n * @param {Provider} provider\n * @param {Uint8Array} archive\n * @param {Uint8Array} snapshot\n * @param {Uint8Array} ciphertext\n * @param {boolean} allow_own_messages\n * @param {number} max_forward_distance\n * @returns {ArchivedMessage}\n */\nexport function decrypt_with_epoch_archive_v2(provider, archive, snapshot, ciphertext, allow_own_messages, max_forward_distance) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(archive, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(snapshot, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passArray8ToWasm0(ciphertext, wasm.__wbindgen_malloc);\n const len2 = WASM_VECTOR_LEN;\n const ret = wasm.decrypt_with_epoch_archive_v2(provider.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, allow_own_messages, max_forward_distance);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ArchivedMessage.__wrap(ret[0]);\n}\n\n/**\n * Decrypt sender data using an archived epoch without consuming the message ratchet.\n * @param {Provider} provider\n * @param {Uint8Array} archive\n * @param {Uint8Array} ciphertext\n * @returns {ArchivedSenderData}\n */\nexport function peek_sender_data_from_archive(provider, archive, ciphertext) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(archive, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(ciphertext, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.peek_sender_data_from_archive(provider.__wbg_ptr, ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ArchivedSenderData.__wrap(ret[0]);\n}\n\n/**\n * Decrypt and verify an MLS private message using archived epoch state.\n *\n * `max_forward_distance` uses `0` as \"use archive default\".\n * @param {Provider} provider\n * @param {Uint8Array} archive\n * @param {Uint8Array} ciphertext\n * @param {boolean} allow_own_messages\n * @param {number} max_forward_distance\n * @returns {ArchivedMessage}\n */\nexport function decrypt_with_epoch_archive(provider, archive, ciphertext, allow_own_messages, max_forward_distance) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(archive, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(ciphertext, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.decrypt_with_epoch_archive(provider.__wbg_ptr, ptr0, len0, ptr1, len1, allow_own_messages, max_forward_distance);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ArchivedMessage.__wrap(ret[0]);\n}\n\n/**\n * Type of processed message\n * @enum {0 | 1 | 2}\n */\nexport const MessageType = Object.freeze({\n /**\n * Application message (encrypted user content)\n */\n ApplicationMessage: 0, \"0\": \"ApplicationMessage\",\n /**\n * Proposal message (add/remove/update)\n */\n Proposal: 1, \"1\": \"Proposal\",\n /**\n * Commit message (finalizing proposals)\n */\n Commit: 2, \"2\": \"Commit\",\n});\n/**\n * Error codes for MLS operations\n * @enum {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10}\n */\nexport const MlsErrorCode = Object.freeze({\n /**\n * Error during serialization\n */\n SerializationError: 0, \"0\": \"SerializationError\",\n /**\n * Error during deserialization\n */\n DeserializationError: 1, \"1\": \"DeserializationError\",\n /**\n * Group is not in operational state\n */\n GroupNotOperational: 2, \"2\": \"GroupNotOperational\",\n /**\n * Member not found in group\n */\n MemberNotFound: 3, \"3\": \"MemberNotFound\",\n /**\n * Invalid message format or content\n */\n InvalidMessage: 4, \"4\": \"InvalidMessage\",\n /**\n * Welcome message was expected but not generated\n */\n NoWelcome: 5, \"5\": \"NoWelcome\",\n /**\n * Invalid CID format\n */\n InvalidCid: 6, \"6\": \"InvalidCid\",\n /**\n * Storage operation failed\n */\n StorageError: 7, \"7\": \"StorageError\",\n /**\n * Crypto operation failed\n */\n CryptoError: 8, \"8\": \"CryptoError\",\n /**\n * Invalid state\n */\n InvalidState: 9, \"9\": \"InvalidState\",\n /**\n * External commit failed\n */\n ExternalCommitError: 10, \"10\": \"ExternalCommitError\",\n});\n\nconst AddMessagesFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_addmessages_free(ptr >>> 0, 1));\n/**\n * Messages generated when adding a member (legacy format)\n */\nexport class AddMessages {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(AddMessages.prototype);\n obj.__wbg_ptr = ptr;\n AddMessagesFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n AddMessagesFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_addmessages_free(ptr, 0);\n }\n /**\n * @returns {Uint8Array | undefined}\n */\n get group_info() {\n const ret = wasm.addmessages_group_info(this.__wbg_ptr);\n let v1;\n if (ret[0] !== 0) {\n v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n }\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get commit() {\n const ret = wasm.addmessages_commit(this.__wbg_ptr);\n return ret;\n }\n /**\n * @returns {Uint8Array}\n */\n get welcome() {\n const ret = wasm.addmessages_welcome(this.__wbg_ptr);\n return ret;\n }\n /**\n * @returns {Uint8Array}\n */\n get proposal() {\n const ret = wasm.addmessages_proposal(this.__wbg_ptr);\n return ret;\n }\n}\n\nconst ArchiveBlobAadFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_archiveblobaad_free(ptr >>> 0, 1));\n\nexport class ArchiveBlobAad {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ArchiveBlobAadFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_archiveblobaad_free(ptr, 0);\n }\n /**\n * @param {string} cid\n * @param {bigint} epoch\n * @param {string} scope\n * @param {string} blob_id\n * @param {string} snapshot_hash\n */\n constructor(cid, epoch, scope, blob_id, snapshot_hash) {\n const ptr0 = passStringToWasm0(cid, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passStringToWasm0(scope, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passStringToWasm0(blob_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len2 = WASM_VECTOR_LEN;\n const ptr3 = passStringToWasm0(snapshot_hash, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len3 = WASM_VECTOR_LEN;\n const ret = wasm.archiveblobaad_new(ptr0, len0, epoch, ptr1, len1, ptr2, len2, ptr3, len3);\n this.__wbg_ptr = ret >>> 0;\n ArchiveBlobAadFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.archiveblobaad_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ArchiveKeyWrapInfoFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_archivekeywrapinfo_free(ptr >>> 0, 1));\n\nexport class ArchiveKeyWrapInfo {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ArchiveKeyWrapInfoFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_archivekeywrapinfo_free(ptr, 0);\n }\n /**\n * @param {string} channel_id\n * @param {bigint} epoch\n * @param {string} scope\n * @param {string} blob_id\n * @param {string} snapshot_hash\n * @param {string} recipient_key_id\n */\n constructor(channel_id, epoch, scope, blob_id, snapshot_hash, recipient_key_id) {\n const ptr0 = passStringToWasm0(channel_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passStringToWasm0(scope, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passStringToWasm0(blob_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len2 = WASM_VECTOR_LEN;\n const ptr3 = passStringToWasm0(snapshot_hash, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len3 = WASM_VECTOR_LEN;\n const ptr4 = passStringToWasm0(recipient_key_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len4 = WASM_VECTOR_LEN;\n const ret = wasm.archivekeywrapinfo_new(ptr0, len0, epoch, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);\n this.__wbg_ptr = ret >>> 0;\n ArchiveKeyWrapInfoFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.archivekeywrapinfo_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ArchivedMessageFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_archivedmessage_free(ptr >>> 0, 1));\n/**\n * Application plaintext recovered from an archived epoch.\n */\nexport class ArchivedMessage {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ArchivedMessage.prototype);\n obj.__wbg_ptr = ptr;\n ArchivedMessageFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ArchivedMessageFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_archivedmessage_free(ptr, 0);\n }\n /**\n * Get the sender ratchet generation.\n * @returns {number}\n */\n get generation() {\n const ret = wasm.archivedmessage_generation(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Whether this message was sent by the archive owner's own leaf.\n * @returns {boolean}\n */\n get own_message() {\n const ret = wasm.archivedmessage_own_message(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get the sender's leaf index.\n * @returns {number}\n */\n get sender_index() {\n const ret = wasm.archivedmessage_sender_index(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Get the additional authenticated data.\n * @returns {Uint8Array}\n */\n get aad() {\n const ret = wasm.archivedmessage_aad(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the MLS epoch.\n * @returns {bigint}\n */\n get epoch() {\n const ret = wasm.archivedmessage_epoch(this.__wbg_ptr);\n return BigInt.asUintN(64, ret);\n }\n /**\n * Get the decrypted application content.\n * @returns {Uint8Array}\n */\n get content() {\n const ret = wasm.archivedmessage_content(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ArchivedSenderDataFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_archivedsenderdata_free(ptr >>> 0, 1));\n/**\n * Sender data decoded from an archived epoch.\n */\nexport class ArchivedSenderData {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ArchivedSenderData.prototype);\n obj.__wbg_ptr = ptr;\n ArchivedSenderDataFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ArchivedSenderDataFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_archivedsenderdata_free(ptr, 0);\n }\n /**\n * Get the sender ratchet generation.\n * @returns {number}\n */\n get generation() {\n const ret = wasm.archivedsenderdata_generation(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Whether this message was sent by the archive owner's own leaf.\n * @returns {boolean}\n */\n get own_message() {\n const ret = wasm.archivedsenderdata_own_message(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get the MLS content type.\n * @returns {string}\n */\n get content_type() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.archivedsenderdata_content_type(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n /**\n * Get the sender's leaf index.\n * @returns {number}\n */\n get sender_index() {\n const ret = wasm.archivedsenderdata_sender_index(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Get the MLS epoch.\n * @returns {bigint}\n */\n get epoch() {\n const ret = wasm.archivedmessage_epoch(this.__wbg_ptr);\n return BigInt.asUintN(64, ret);\n }\n}\n\nconst CommitBundleFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_commitbundle_free(ptr >>> 0, 1));\n/**\n * Bundle containing commit message and optional welcome\n */\nexport class CommitBundle {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(CommitBundle.prototype);\n obj.__wbg_ptr = ptr;\n CommitBundleFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n CommitBundleFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_commitbundle_free(ptr, 0);\n }\n /**\n * Get the group info bytes\n * @returns {Uint8Array | undefined}\n */\n get group_info() {\n const ret = wasm.commitbundle_group_info(this.__wbg_ptr);\n let v1;\n if (ret[0] !== 0) {\n v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n }\n return v1;\n }\n /**\n * Check if this commit includes a welcome (new members added)\n * @returns {boolean}\n */\n has_welcome() {\n const ret = wasm.commitbundle_has_welcome(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get commit as Uint8Array\n * @returns {Uint8Array}\n */\n commit_as_uint8array() {\n const ret = wasm.commitbundle_commit_as_uint8array(this.__wbg_ptr);\n return ret;\n }\n /**\n * Get welcome as Uint8Array (returns empty if no welcome)\n * @returns {Uint8Array}\n */\n welcome_as_uint8array() {\n const ret = wasm.commitbundle_welcome_as_uint8array(this.__wbg_ptr);\n return ret;\n }\n /**\n * Get the commit message bytes\n * @returns {Uint8Array}\n */\n get commit() {\n const ret = wasm.commitbundle_commit(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the welcome message bytes (if any new members were added)\n * @returns {Uint8Array | undefined}\n */\n get welcome() {\n const ret = wasm.commitbundle_welcome(this.__wbg_ptr);\n let v1;\n if (ret[0] !== 0) {\n v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n }\n return v1;\n }\n}\n\nconst EncryptedArchiveBlobFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_encryptedarchiveblob_free(ptr >>> 0, 1));\n\nexport class EncryptedArchiveBlob {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(EncryptedArchiveBlob.prototype);\n obj.__wbg_ptr = ptr;\n EncryptedArchiveBlobFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n EncryptedArchiveBlobFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_encryptedarchiveblob_free(ptr, 0);\n }\n /**\n * @returns {Uint8Array}\n */\n get ciphertext() {\n const ret = wasm.encryptedarchiveblob_ciphertext(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get adk() {\n const ret = wasm.encryptedarchiveblob_adk(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get nonce() {\n const ret = wasm.encryptedarchiveblob_nonce(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get aead_aad() {\n const ret = wasm.encryptedarchiveblob_aead_aad(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ExportedEpochArchiveV2Finalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_exportedepocharchivev2_free(ptr >>> 0, 1));\n\nexport class ExportedEpochArchiveV2 {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ExportedEpochArchiveV2.prototype);\n obj.__wbg_ptr = ptr;\n ExportedEpochArchiveV2Finalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ExportedEpochArchiveV2Finalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_exportedepocharchivev2_free(ptr, 0);\n }\n /**\n * @returns {Uint8Array}\n */\n get archive_bytes() {\n const ret = wasm.exportedepocharchivev2_archive_bytes(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get snapshot_hash() {\n const ret = wasm.exportedepocharchivev2_snapshot_hash(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get snapshot_bytes() {\n const ret = wasm.exportedepocharchivev2_snapshot_bytes(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ExternalJoinResultFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_externaljoinresult_free(ptr >>> 0, 1));\n/**\n * Result of an external join (self-join with GroupInfo)\n */\nexport class ExternalJoinResult {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ExternalJoinResult.prototype);\n obj.__wbg_ptr = ptr;\n ExternalJoinResultFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ExternalJoinResultFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_externaljoinresult_free(ptr, 0);\n }\n /**\n * Get the joined group\n * @returns {Group | undefined}\n */\n get group() {\n const ret = wasm.externaljoinresult_group(this.__wbg_ptr);\n return ret === 0 ? undefined : Group.__wrap(ret);\n }\n /**\n * Get the commit message to broadcast\n * @returns {Uint8Array}\n */\n get commit() {\n const ret = wasm.externaljoinresult_commit(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst GroupFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_group_free(ptr >>> 0, 1));\n/**\n * An MLS Group representing an encrypted channel\n */\nexport class Group {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(Group.prototype);\n obj.__wbg_ptr = ptr;\n GroupFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n GroupFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_group_free(ptr, 0);\n }\n /**\n * Create a new group (legacy API, uses group_id string directly)\n * @param {Provider} provider\n * @param {Identity} founder\n * @param {string} group_id\n * @returns {Group}\n */\n static create_new(provider, founder, group_id) {\n _assertClass(provider, Provider);\n _assertClass(founder, Identity);\n const ptr0 = passStringToWasm0(group_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_create_new(provider.__wbg_ptr, founder.__wbg_ptr, ptr0, len0);\n return Group.__wrap(ret);\n }\n /**\n * Persist the group's current state to the Provider's storage.\n *\n * MUST be called after processing application messages (decrypt) to save\n * the updated ratchet/secret tree state. Without this, a Provider restore\n * (e.g., on page reload) will load stale ratchet state, causing\n * SecretReuseError for messages that were already decrypted.\n * @param {Provider} provider\n */\n save_state(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.group_save_state(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * Delete this group's persisted OpenMLS state from the Provider storage.\n *\n * Use when the local user leaves or is removed from a channel. This clears\n * the old MLS group state so a later re-add with the same CID can join from\n * a fresh Welcome without colliding with stale provider records.\n * @param {Provider} provider\n */\n delete_state(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.group_delete_state(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * Join a group via External Commit\n *\n * This allows a user to join a group without needing a Welcome message,\n * using only the GroupInfo.\n *\n * # Arguments\n * * `provider` - Crypto provider\n * * `identity` - Identity of the joiner\n * * `group_info` - Serialized GroupInfo bytes\n * * `ratchet_tree` - Optional ratchet tree\n *\n * # Returns\n * ExternalJoinResult containing the joined group and commit message to broadcast\n * @param {Provider} provider\n * @param {Identity} identity\n * @param {Uint8Array} group_info\n * @param {RatchetTree | null} [ratchet_tree]\n * @returns {ExternalJoinResult}\n */\n static join_external(provider, identity, group_info, ratchet_tree) {\n _assertClass(provider, Provider);\n _assertClass(identity, Identity);\n const ptr0 = passArray8ToWasm0(group_info, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n let ptr1 = 0;\n if (!isLikeNone(ratchet_tree)) {\n _assertClass(ratchet_tree, RatchetTree);\n ptr1 = ratchet_tree.__destroy_into_raw();\n }\n const ret = wasm.group_join_external(provider.__wbg_ptr, identity.__wbg_ptr, ptr0, len0, ptr1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ExternalJoinResult.__wrap(ret[0]);\n }\n /**\n * Create a new group with a CID from Ermis\n *\n * # Arguments\n * * `provider` - Crypto provider\n * * `founder` - Identity of the group creator\n * * `cid` - Channel ID from Ermis (e.g., \"team:channel_abc123\")\n *\n * # Example\n * ```javascript\n * const group = Group.create_with_cid(provider, identity, \"team:my_channel\");\n * ```\n * @param {Provider} provider\n * @param {Identity} founder\n * @param {string} cid\n * @returns {Group}\n */\n static create_with_cid(provider, founder, cid) {\n _assertClass(provider, Provider);\n _assertClass(founder, Identity);\n const ptr0 = passStringToWasm0(cid, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_create_with_cid(provider.__wbg_ptr, founder.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Group.__wrap(ret[0]);\n }\n /**\n * Join a group using a Welcome message\n *\n * # Arguments\n * * `provider` - Crypto provider\n * * `welcome` - Serialized Welcome message bytes\n * * `ratchet_tree` - Optional ratchet tree (if not embedded in welcome)\n * @param {Provider} provider\n * @param {Uint8Array} welcome\n * @param {RatchetTree | null} [ratchet_tree]\n * @returns {Group}\n */\n static join_with_welcome(provider, welcome, ratchet_tree) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(welcome, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n let ptr1 = 0;\n if (!isLikeNone(ratchet_tree)) {\n _assertClass(ratchet_tree, RatchetTree);\n ptr1 = ratchet_tree.__destroy_into_raw();\n }\n const ret = wasm.group_join_with_welcome(provider.__wbg_ptr, ptr0, len0, ptr1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Group.__wrap(ret[0]);\n }\n /**\n * Join a group using a Welcome (legacy API)\n * @param {Provider} provider\n * @param {Uint8Array} welcome\n * @param {RatchetTree} ratchet_tree\n * @returns {Group}\n */\n static join(provider, welcome, ratchet_tree) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(welcome, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n _assertClass(ratchet_tree, RatchetTree);\n var ptr1 = ratchet_tree.__destroy_into_raw();\n const ret = wasm.group_join(provider.__wbg_ptr, ptr0, len0, ptr1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Group.__wrap(ret[0]);\n }\n /**\n * Load a group from the Provider's storage by CID\n *\n * After restoring a Provider from bytes (IndexedDB), call this to reopen\n * a group that was previously created or joined.\n *\n * # Arguments\n * * `provider` - Crypto provider (restored from bytes)\n * * `cid` - Channel ID (e.g., \"team:channel_abc123\")\n * @param {Provider} provider\n * @param {string} cid\n * @returns {Group}\n */\n static load(provider, cid) {\n _assertClass(provider, Provider);\n const ptr0 = passStringToWasm0(cid, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_load(provider.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Group.__wrap(ret[0]);\n }\n /**\n * Export a secret key derived from the group state\n *\n * Useful for deriving encryption keys for media streams, etc.\n * @param {Provider} provider\n * @param {string} label\n * @param {Uint8Array} context\n * @param {number} key_length\n * @returns {Uint8Array}\n */\n export_key(provider, label, context, key_length) {\n _assertClass(provider, Provider);\n const ptr0 = passStringToWasm0(label, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(context, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.group_export_key(this.__wbg_ptr, provider.__wbg_ptr, ptr0, len0, ptr1, len1, key_length);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v3;\n }\n /**\n * Check if the group is in operational state\n *\n * Returns false if there's a pending commit or the group is inactive\n * @returns {boolean}\n */\n is_operational() {\n const ret = wasm.group_is_operational(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get the local member's leaf index\n * @returns {number}\n */\n own_leaf_index() {\n const ret = wasm.group_own_leaf_index(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Export V2 archive bytes plus canonical member snapshot.\n * @returns {ExportedEpochArchiveV2}\n */\n archive_epoch_v2() {\n const ret = wasm.group_archive_epoch_v2(this.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ExportedEpochArchiveV2.__wrap(ret[0]);\n }\n /**\n * Export group info for external commits\n *\n * # Arguments\n * * `with_ratchet_tree` - Whether to include the ratchet tree in the group info\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {boolean} with_ratchet_tree\n * @returns {Uint8Array}\n */\n export_group_info(provider, sender, with_ratchet_tree) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_export_group_info(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, with_ratchet_tree);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get a member by user_id (returns first match)\n * @param {string} user_id\n * @returns {MemberInfo | undefined}\n */\n member_by_user_id(user_id) {\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_member_by_user_id(this.__wbg_ptr, ptr0, len0);\n return ret === 0 ? undefined : MemberInfo.__wrap(ret);\n }\n /**\n * Check if there's a pending commit that hasn't been merged\n * @returns {boolean}\n */\n has_pending_commit() {\n const ret = wasm.group_has_pending_commit(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get ALL members (leaf nodes) for a given user_id\n *\n * A user with N devices will have N entries in the group.\n * Use this to find all leaf indices for a multi-device user.\n * @param {string} user_id\n * @returns {MemberInfo[]}\n */\n members_by_user_id(user_id) {\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_members_by_user_id(this.__wbg_ptr, ptr0, len0);\n var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);\n return v2;\n }\n /**\n * Export the ratchet tree for sharing with new members\n * @returns {RatchetTree}\n */\n export_ratchet_tree() {\n const ret = wasm.group_export_ratchet_tree(this.__wbg_ptr);\n return RatchetTree.__wrap(ret);\n }\n /**\n * Export the current epoch archive for historical message recovery.\n *\n * The returned bytes contain MLS secret material. Applications must encrypt\n * them with their PIN/vault key before uploading or persisting outside the\n * local device.\n * @returns {Uint8Array}\n */\n archive_current_epoch() {\n const ret = wasm.group_archive_current_epoch(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the CID (group_id as string)\n *\n * This returns the original cid string used to create the group,\n * matching the Ermis channel cid format (e.g., \"team:channel_abc123\")\n * @returns {string}\n */\n cid() {\n let deferred2_0;\n let deferred2_1;\n try {\n const ret = wasm.group_cid(this.__wbg_ptr);\n var ptr1 = ret[0];\n var len1 = ret[1];\n if (ret[3]) {\n ptr1 = 0; len1 = 0;\n throw takeFromExternrefTable0(ret[2]);\n }\n deferred2_0 = ptr1;\n deferred2_1 = len1;\n return getStringFromWasm0(ptr1, len1);\n } finally {\n wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);\n }\n }\n /**\n * Get current epoch number\n *\n * Epoch increases with each commit\n * @returns {bigint}\n */\n epoch() {\n const ret = wasm.group_epoch(this.__wbg_ptr);\n return BigInt.asUintN(64, ret);\n }\n /**\n * Get all members in the group\n * @returns {MemberInfo[]}\n */\n members() {\n const ret = wasm.group_members(this.__wbg_ptr);\n var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);\n return v1;\n }\n /**\n * Get the raw group_id bytes\n * @returns {Uint8Array}\n */\n group_id() {\n const ret = wasm.group_group_id(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Add members and commit immediately (convenience method)\n *\n * Use this when you want to add members without batching.\n * For batch operations, use `propose_add_member` + `commit_pending_proposals`.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {KeyPackage[]} new_members\n * @returns {CommitBundle}\n */\n add_members(provider, sender, new_members) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(new_members, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_add_members(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Remove ALL devices of a user by user_id and commit immediately\n *\n * A user with N devices will have N leaf nodes in the group.\n * This method finds all of them and removes them in a single commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string} user_id\n * @returns {CommitBundle}\n */\n remove_user(provider, sender, user_id) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_remove_user(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Key rotation with immediate commit (convenience method)\n * @param {Provider} provider\n * @param {Identity} sender\n * @returns {CommitBundle}\n */\n self_update(provider, sender) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_self_update(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Remove multiple users (all their devices) and commit immediately\n *\n * Each user_id may have multiple leaf nodes (devices).\n * This method finds ALL leaf nodes for ALL specified users\n * and removes them in a single commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string[]} user_ids\n * @returns {CommitBundle}\n */\n remove_users(provider, sender, user_ids) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(user_ids, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_remove_users(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Remove members and commit immediately (convenience method)\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {Uint32Array} member_indices\n * @returns {CommitBundle}\n */\n remove_members(provider, sender, member_indices) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArray32ToWasm0(member_indices, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_remove_members(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Discard the pending commit (rollback)\n * @param {Provider} provider\n */\n clear_pending_commit(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.group_clear_pending_commit(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * Create one inline commit containing removals, adds, and/or a self-update.\n *\n * This API uses `commit_builder().consume_proposal_store(false)` so the\n * resulting commit contains only the changes requested by this call. The\n * remove/add proposals are owned by the commit and encoded by value, which\n * avoids receivers depending on standalone proposal messages being delivered\n * before the commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string[]} remove_user_ids\n * @param {KeyPackage[]} add_members\n * @param {boolean} force_self_update\n * @returns {CommitBundle}\n */\n commit_group_changes(provider, sender, remove_user_ids, add_members, force_self_update) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(remove_user_ids, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArrayJsValueToWasm0(add_members, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.group_commit_group_changes(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0, ptr1, len1, force_self_update);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Merge the pending commit after DS confirmation\n * @param {Provider} provider\n */\n merge_pending_commit(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.group_merge_pending_commit(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * Create one inline commit that removes one or more members.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string[]} remove_user_ids\n * @returns {CommitBundle}\n */\n commit_member_removals(provider, sender, remove_user_ids) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(remove_user_ids, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_commit_member_removals(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Combined propose and commit for adding a single member\n * This is kept for backwards compatibility with demo code\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {KeyPackage} new_member\n * @returns {AddMessages}\n */\n propose_and_commit_add(provider, sender, new_member) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n _assertClass(new_member, KeyPackage);\n const ret = wasm.group_propose_and_commit_add(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, new_member.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return AddMessages.__wrap(ret[0]);\n }\n /**\n * Commit all pending proposals\n *\n * This creates a commit message that includes all queued proposals.\n * Use `merge_pending_commit` after the DS confirms the commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @returns {CommitBundle}\n */\n commit_pending_proposals(provider, sender) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_commit_pending_proposals(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Create one inline commit that removes stale members and adds new members.\n *\n * This is an intent-specific wrapper for SDK callsites. It intentionally\n * shares the implementation of `commit_group_changes` so duplicate\n * add/remove validation cannot drift.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string[]} remove_user_ids\n * @param {KeyPackage[]} add_members\n * @returns {CommitBundle}\n */\n commit_member_add_with_removals(provider, sender, remove_user_ids, add_members) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(remove_user_ids, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArrayJsValueToWasm0(add_members, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.group_commit_member_add_with_removals(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Create one inline commit that removes stale members and rotates the sender leaf.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string[]} remove_user_ids\n * @returns {CommitBundle}\n */\n commit_self_update_with_removals(provider, sender, remove_user_ids) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(remove_user_ids, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_commit_self_update_with_removals(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Add a user with multiple devices and commit immediately\n *\n * Each KeyPackage represents one device of the same user.\n * All devices are added in a single commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {KeyPackage[]} device_key_packages\n * @returns {CommitBundle}\n */\n add_user(provider, sender, device_key_packages) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(device_key_packages, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_add_user(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return CommitBundle.__wrap(ret[0]);\n }\n /**\n * Leave the group by creating a self-remove proposal\n *\n * Creates a Remove Proposal for the caller's own leaf node.\n * This proposal must be sent to the server and committed by another member.\n * The caller should NOT commit this proposal themselves.\n *\n * Returns the serialized proposal message bytes.\n * @param {Provider} provider\n * @param {Identity} sender\n * @returns {Uint8Array}\n */\n leave_group(provider, sender) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_leave_group(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Propose adding a user with multiple devices (does NOT commit immediately)\n *\n * Each KeyPackage represents one device. Creates one add proposal\n * per device, all queued as pending proposals.\n * Call `commit_pending_proposals` to batch them into a single commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {KeyPackage[]} device_key_packages\n * @returns {ProposalMessage[]}\n */\n propose_add_user(provider, sender, device_key_packages) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArrayJsValueToWasm0(device_key_packages, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_propose_add_user(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);\n return v2;\n }\n /**\n * Propose adding a new member (does NOT commit immediately)\n *\n * Use this when you want to batch multiple proposals before committing.\n * Call `commit_pending_proposals` after queuing all proposals.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {KeyPackage} new_member\n * @returns {ProposalMessage}\n */\n propose_add_member(provider, sender, new_member) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n _assertClass(new_member, KeyPackage);\n const ret = wasm.group_propose_add_member(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, new_member.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ProposalMessage.__wrap(ret[0]);\n }\n /**\n * Propose removing ALL devices of a user by user_id\n *\n * A user with N devices will have N leaf nodes. This creates\n * one remove proposal per device. Call `commit_pending_proposals`\n * after this to finalize all removals in a single commit.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string} user_id\n * @returns {ProposalMessage[]}\n */\n propose_remove_user(provider, sender, user_id) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_propose_remove_user(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);\n return v2;\n }\n /**\n * Propose a self-update (key rotation for forward secrecy)\n * @param {Provider} provider\n * @param {Identity} sender\n * @returns {ProposalMessage}\n */\n propose_self_update(provider, sender) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_propose_self_update(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ProposalMessage.__wrap(ret[0]);\n }\n /**\n * Propose removing a member by leaf index\n *\n * Use `member_by_user_id` to get the leaf index from a user_id.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {number} member_index\n * @returns {ProposalMessage}\n */\n propose_remove_member(provider, sender, member_index) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ret = wasm.group_propose_remove_member(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, member_index);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ProposalMessage.__wrap(ret[0]);\n }\n /**\n * Clear all pending proposals without committing\n * @param {Provider} provider\n */\n clear_pending_proposals(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.group_clear_pending_proposals(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * Get the number of pending proposals\n * @returns {number}\n */\n pending_proposals_count() {\n const ret = wasm.group_pending_proposals_count(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Propose removing a member by user_id\n *\n * This is a convenience method that finds the member by credential\n * and proposes their removal.\n * Note: This only removes ONE leaf node. For multi-device users,\n * use `propose_remove_user` instead.\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {string} user_id\n * @returns {ProposalMessage}\n */\n propose_remove_member_by_user_id(provider, sender, user_id) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_propose_remove_member_by_user_id(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ProposalMessage.__wrap(ret[0]);\n }\n /**\n * Create an encrypted message\n *\n * # Arguments\n * * `provider` - Crypto provider\n * * `sender` - Identity of the sender\n * * `plaintext` - The message content to encrypt\n * 1\n * # Returns\n * Serialized encrypted MLS message\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {Uint8Array} plaintext\n * @returns {Uint8Array}\n */\n create_message(provider, sender, plaintext) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArray8ToWasm0(plaintext, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_create_message(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v2;\n }\n /**\n * Process an incoming message (decrypt or handle proposal/commit)\n *\n * This method handles all MLS message types:\n * - ApplicationMessage: Returns decrypted content\n * - Proposal: Stores as pending proposal, returns empty content\n * - Commit: Merges the staged commit, returns empty content\n * @param {Provider} provider\n * @param {Uint8Array} msg\n * @returns {ProcessedMessage}\n */\n process_message(provider, msg) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(msg, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_process_message(this.__wbg_ptr, provider.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ProcessedMessage.__wrap(ret[0]);\n }\n /**\n * Process message and return raw bytes (legacy API, for backwards compatibility)\n *\n * Returns decrypted bytes for application messages, empty for proposals/commits.\n * @param {Provider} provider\n * @param {Uint8Array} msg\n * @returns {Uint8Array}\n */\n process_message_raw(provider, msg) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(msg, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.group_process_message_raw(this.__wbg_ptr, provider.__wbg_ptr, ptr0, len0);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v2;\n }\n /**\n * Create an encrypted message with AAD in one call\n *\n * This is a convenience method that sets AAD and creates the message.\n *\n * # Arguments\n * * `provider` - Crypto provider\n * * `sender` - Identity of the sender\n * * `plaintext` - The message content to encrypt\n * * `aad` - Additional authenticated data (metadata to bind to ciphertext)\n * @param {Provider} provider\n * @param {Identity} sender\n * @param {Uint8Array} plaintext\n * @param {Uint8Array} aad\n * @returns {Uint8Array}\n */\n create_message_with_aad(provider, sender, plaintext, aad) {\n _assertClass(provider, Provider);\n _assertClass(sender, Identity);\n const ptr0 = passArray8ToWasm0(plaintext, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(aad, wasm.__wbindgen_malloc);\n const len1 = WASM_VECTOR_LEN;\n const ret = wasm.group_create_message_with_aad(this.__wbg_ptr, provider.__wbg_ptr, sender.__wbg_ptr, ptr0, len0, ptr1, len1);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v3;\n }\n /**\n * Set Additional Authenticated Data (AAD) for the next outgoing message\n *\n * AAD is authenticated but NOT encrypted - use for metadata that needs\n * to be bound cryptographically to the ciphertext (e.g., sender_id, channel_id).\n * AAD is automatically reset after create_message() is called.\n *\n * # Arguments\n * * `aad` - Bytes to use as AAD (typically JSON-serialized metadata)\n * @param {Uint8Array} aad\n */\n set_aad(aad) {\n const ptr0 = passArray8ToWasm0(aad, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n wasm.group_set_aad(this.__wbg_ptr, ptr0, len0);\n }\n}\n\nconst HpkeWrappedArchiveDataKeyFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_hpkewrappedarchivedatakey_free(ptr >>> 0, 1));\n\nexport class HpkeWrappedArchiveDataKey {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(HpkeWrappedArchiveDataKey.prototype);\n obj.__wbg_ptr = ptr;\n HpkeWrappedArchiveDataKeyFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n HpkeWrappedArchiveDataKeyFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_hpkewrappedarchivedatakey_free(ptr, 0);\n }\n /**\n * @returns {Uint8Array}\n */\n get ciphertext() {\n const ret = wasm.hpkewrappedarchivedatakey_ciphertext(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @param {Uint8Array} bytes\n * @returns {HpkeWrappedArchiveDataKey}\n */\n static from_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.hpkewrappedarchivedatakey_from_bytes(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return HpkeWrappedArchiveDataKey.__wrap(ret[0]);\n }\n /**\n * @returns {Uint8Array}\n */\n get kem_output() {\n const ret = wasm.hpkewrappedarchivedatakey_kem_output(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {number}\n */\n get ciphersuite() {\n const ret = wasm.hpkewrappedarchivedatakey_ciphersuite(this.__wbg_ptr);\n return ret;\n }\n /**\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.hpkewrappedarchivedatakey_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {Uint8Array}\n */\n get hpke_info() {\n const ret = wasm.hpkewrappedarchivedatakey_hpke_info(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst IdentityFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_identity_free(ptr >>> 0, 1));\n/**\n * Represents a user's MLS identity with credentials and signing keys\n */\nexport class Identity {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(Identity.prototype);\n obj.__wbg_ptr = ptr;\n IdentityFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IdentityFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_identity_free(ptr, 0);\n }\n /**\n * Restore identity from bytes\n * @param {Provider} provider\n * @param {Uint8Array} bytes\n * @returns {Identity}\n */\n static from_bytes(provider, bytes) {\n _assertClass(provider, Provider);\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.identity_from_bytes(provider.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Identity.__wrap(ret[0]);\n }\n /**\n * Generate a single key package for this identity\n * @param {Provider} provider\n * @returns {KeyPackage}\n */\n key_package(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.identity_key_package(this.__wbg_ptr, provider.__wbg_ptr);\n return KeyPackage.__wrap(ret);\n }\n /**\n * Generate multiple key packages for multi-device support\n *\n * # Arguments\n * * `provider` - The crypto provider\n * * `count` - Number of key packages to generate\n * @param {Provider} provider\n * @param {number} count\n * @returns {KeyPackage[]}\n */\n key_packages(provider, count) {\n _assertClass(provider, Provider);\n const ret = wasm.identity_key_packages(this.__wbg_ptr, provider.__wbg_ptr, count);\n var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);\n return v1;\n }\n /**\n * Create a new identity for a user\n *\n * # Arguments\n * * `provider` - The crypto provider\n * * `user_id` - Unique identifier for the user (e.g., from Ermis user system)\n * @param {Provider} provider\n * @param {string} user_id\n */\n constructor(provider, user_id) {\n _assertClass(provider, Provider);\n const ptr0 = passStringToWasm0(user_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.identity_new(provider.__wbg_ptr, ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n this.__wbg_ptr = ret[0] >>> 0;\n IdentityFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * Get the user_id from this identity\n * @returns {string}\n */\n get user_id() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.identity_user_id(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n /**\n * Serialize identity for storage\n * Note: This only exports the keypair, credential will be reconstructed\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.identity_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst KeyPackageFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_keypackage_free(ptr >>> 0, 1));\n/**\n * A KeyPackage for joining groups\n */\nexport class KeyPackage {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(KeyPackage.prototype);\n obj.__wbg_ptr = ptr;\n KeyPackageFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n static __unwrap(jsValue) {\n if (!(jsValue instanceof KeyPackage)) {\n return 0;\n }\n return jsValue.__destroy_into_raw();\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n KeyPackageFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_keypackage_free(ptr, 0);\n }\n /**\n * Deserialize a KeyPackage from bytes\n * @param {Uint8Array} bytes\n * @returns {KeyPackage}\n */\n static from_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.keypackage_from_bytes(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return KeyPackage.__wrap(ret[0]);\n }\n /**\n * Get the hash reference of this key package\n * @param {Provider} provider\n * @returns {Uint8Array}\n */\n hash_ref(provider) {\n _assertClass(provider, Provider);\n const ret = wasm.keypackage_hash_ref(this.__wbg_ptr, provider.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Serialize this KeyPackage to bytes\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.keypackage_to_bytes(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst MemberInfoFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_memberinfo_free(ptr >>> 0, 1));\n/**\n * Information about a group member\n */\nexport class MemberInfo {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(MemberInfo.prototype);\n obj.__wbg_ptr = ptr;\n MemberInfoFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n MemberInfoFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_memberinfo_free(ptr, 0);\n }\n /**\n * Get the member's signature key\n * @returns {Uint8Array}\n */\n get signature_key() {\n const ret = wasm.memberinfo_signature_key(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the member's encryption key\n * @returns {Uint8Array}\n */\n get encryption_key() {\n const ret = wasm.memberinfo_encryption_key(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the member's leaf index\n * @returns {number}\n */\n get index() {\n const ret = wasm.memberinfo_index(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Get the member's user_id\n * @returns {string}\n */\n get user_id() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.memberinfo_user_id(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n}\n\nconst MlsErrorFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_mlserror_free(ptr >>> 0, 1));\n/**\n * Custom error type for MLS operations\n */\nexport class MlsError {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n MlsErrorFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_mlserror_free(ptr, 0);\n }\n /**\n * Create a new MlsError\n * @param {MlsErrorCode} code\n * @param {string} message\n */\n constructor(code, message) {\n const ptr0 = passStringToWasm0(message, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.mlserror_new(code, ptr0, len0);\n this.__wbg_ptr = ret >>> 0;\n MlsErrorFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * Get error code\n * @returns {MlsErrorCode}\n */\n get code() {\n const ret = wasm.mlserror_code(this.__wbg_ptr);\n return ret;\n }\n /**\n * Get error message\n * @returns {string}\n */\n get message() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.mlserror_message(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n}\n\nconst ProcessedMessageFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_processedmessage_free(ptr >>> 0, 1));\n/**\n * Result of processing an incoming message\n */\nexport class ProcessedMessage {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ProcessedMessage.prototype);\n obj.__wbg_ptr = ptr;\n ProcessedMessageFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ProcessedMessageFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_processedmessage_free(ptr, 0);\n }\n /**\n * Check if this is a proposal\n * @returns {boolean}\n */\n is_proposal() {\n const ret = wasm.processedmessage_is_proposal(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get the type of message\n * @returns {MessageType}\n */\n get message_type() {\n const ret = wasm.processedmessage_message_type(this.__wbg_ptr);\n return ret;\n }\n /**\n * Get the sender's leaf index\n * @returns {number}\n */\n get sender_index() {\n const ret = wasm.archivedmessage_sender_index(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * Check if this is an application message\n * @returns {boolean}\n */\n is_application_message() {\n const ret = wasm.processedmessage_is_application_message(this.__wbg_ptr);\n return ret !== 0;\n }\n /**\n * Get the Additional Authenticated Data (AAD) from the message\n * This is the metadata that was bound to the ciphertext during encryption\n * @returns {Uint8Array}\n */\n get aad() {\n const ret = wasm.processedmessage_aad(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get the epoch this message belongs to\n * @returns {bigint}\n */\n get epoch() {\n const ret = wasm.archivedmessage_epoch(this.__wbg_ptr);\n return BigInt.asUintN(64, ret);\n }\n /**\n * Get the decrypted content (only for ApplicationMessage)\n * @returns {Uint8Array | undefined}\n */\n get content() {\n const ret = wasm.processedmessage_content(this.__wbg_ptr);\n let v1;\n if (ret[0] !== 0) {\n v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n }\n return v1;\n }\n /**\n * Check if this is a commit\n * @returns {boolean}\n */\n is_commit() {\n const ret = wasm.processedmessage_is_commit(this.__wbg_ptr);\n return ret !== 0;\n }\n}\n\nconst ProposalMessageFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_proposalmessage_free(ptr >>> 0, 1));\n/**\n * A proposal message that can be sent to other group members\n */\nexport class ProposalMessage {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ProposalMessage.prototype);\n obj.__wbg_ptr = ptr;\n ProposalMessageFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ProposalMessageFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_proposalmessage_free(ptr, 0);\n }\n /**\n * Get the proposal reference for tracking\n * @returns {Uint8Array}\n */\n get proposal_ref() {\n const ret = wasm.proposalmessage_proposal_ref(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * Get bytes as Uint8Array for JavaScript\n * @returns {Uint8Array}\n */\n bytes_as_uint8array() {\n const ret = wasm.proposalmessage_bytes_as_uint8array(this.__wbg_ptr);\n return ret;\n }\n /**\n * Get the serialized proposal message bytes\n * @returns {Uint8Array}\n */\n get bytes() {\n const ret = wasm.proposalmessage_bytes(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst ProviderFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_provider_free(ptr >>> 0, 1));\n/**\n * Crypto provider for MLS operations\n */\nexport class Provider {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(Provider.prototype);\n obj.__wbg_ptr = ptr;\n ProviderFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ProviderFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_provider_free(ptr, 0);\n }\n /**\n * Restore a Provider from previously serialized bytes\n *\n * The crypto provider (RNG) is always fresh; only the key store\n * (private keys, group state, etc.) is restored from bytes.\n * @param {Uint8Array} bytes\n * @returns {Provider}\n */\n static from_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.provider_from_bytes(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return Provider.__wrap(ret[0]);\n }\n constructor() {\n const ret = wasm.provider_new();\n this.__wbg_ptr = ret >>> 0;\n ProviderFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * Serialize the key store to bytes for persistence (e.g. IndexedDB)\n *\n * Returns the serialized key store as a byte array.\n * Use `Provider.from_bytes()` to restore.\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.provider_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst RatchetTreeFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_ratchettree_free(ptr >>> 0, 1));\n/**\n * Ratchet tree for group state synchronization\n */\nexport class RatchetTree {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(RatchetTree.prototype);\n obj.__wbg_ptr = ptr;\n RatchetTreeFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RatchetTreeFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_ratchettree_free(ptr, 0);\n }\n /**\n * Deserialize a RatchetTree from bytes\n * @param {Uint8Array} bytes\n * @returns {RatchetTree}\n */\n static from_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.ratchettree_from_bytes(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return RatchetTree.__wrap(ret[0]);\n }\n /**\n * Serialize this RatchetTree to bytes\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.ratchettree_to_bytes(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nconst RecoveryKeypairFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_recoverykeypair_free(ptr >>> 0, 1));\n\nexport class RecoveryKeypair {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(RecoveryKeypair.prototype);\n obj.__wbg_ptr = ptr;\n RecoveryKeypairFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n RecoveryKeypairFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_recoverykeypair_free(ptr, 0);\n }\n /**\n * @returns {Uint8Array}\n */\n get public_key() {\n const ret = wasm.recoverykeypair_public_key(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {number}\n */\n get ciphersuite() {\n const ret = wasm.hpkewrappedarchivedatakey_ciphersuite(this.__wbg_ptr);\n return ret;\n }\n /**\n * @returns {Uint8Array}\n */\n get private_key() {\n const ret = wasm.recoverykeypair_private_key(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {string}\n */\n get key_id() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.recoverykeypair_key_id(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n}\n\nconst WrappedRecoveryKeyFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_wrappedrecoverykey_free(ptr >>> 0, 1));\n\nexport class WrappedRecoveryKey {\n\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(WrappedRecoveryKey.prototype);\n obj.__wbg_ptr = ptr;\n WrappedRecoveryKeyFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n WrappedRecoveryKeyFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_wrappedrecoverykey_free(ptr, 0);\n }\n /**\n * @param {Uint8Array} bytes\n * @returns {WrappedRecoveryKey}\n */\n static from_bytes(bytes) {\n const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.wrappedrecoverykey_from_bytes(ptr0, len0);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return WrappedRecoveryKey.__wrap(ret[0]);\n }\n /**\n * @returns {Uint8Array}\n */\n get public_key() {\n const ret = wasm.wrappedrecoverykey_public_key(this.__wbg_ptr);\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n /**\n * @returns {number}\n */\n get ciphersuite() {\n const ret = wasm.wrappedrecoverykey_ciphersuite(this.__wbg_ptr);\n return ret;\n }\n /**\n * @returns {string}\n */\n get key_id() {\n let deferred1_0;\n let deferred1_1;\n try {\n const ret = wasm.wrappedrecoverykey_key_id(this.__wbg_ptr);\n deferred1_0 = ret[0];\n deferred1_1 = ret[1];\n return getStringFromWasm0(ret[0], ret[1]);\n } finally {\n wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);\n }\n }\n /**\n * @returns {Uint8Array}\n */\n to_bytes() {\n const ret = wasm.wrappedrecoverykey_to_bytes(this.__wbg_ptr);\n if (ret[3]) {\n throw takeFromExternrefTable0(ret[2]);\n }\n var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();\n wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);\n return v1;\n }\n}\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n\n } catch (e) {\n if (module.headers.get('Content-Type') != 'application/wasm') {\n globalThis.__ermisSdkLog?.('warn', \"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else {\n throw e;\n }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n\n } else {\n return instance;\n }\n }\n}\n\nfunction __wbg_get_imports() {\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbg_alert_28f254ad01ccf9c4 = function(arg0, arg1) {\n alert(getStringFromWasm0(arg0, arg1));\n };\n imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {\n const ret = arg0.buffer;\n return ret;\n };\n imports.wbg.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) {\n const ret = arg0.call(arg1);\n return ret;\n }, arguments) };\n imports.wbg.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = arg0.call(arg1, arg2);\n return ret;\n }, arguments) };\n imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {\n const ret = arg0.crypto;\n return ret;\n };\n imports.wbg.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {\n let deferred0_0;\n let deferred0_1;\n try {\n deferred0_0 = arg0;\n deferred0_1 = arg1;\n globalThis.__ermisSdkLog?.('error', getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n }\n };\n imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {\n arg0.getRandomValues(arg1);\n }, arguments) };\n imports.wbg.__wbg_keypackage_new = function(arg0) {\n const ret = KeyPackage.__wrap(arg0);\n return ret;\n };\n imports.wbg.__wbg_keypackage_unwrap = function(arg0) {\n const ret = KeyPackage.__unwrap(arg0);\n return ret;\n };\n imports.wbg.__wbg_memberinfo_new = function(arg0) {\n const ret = MemberInfo.__wrap(arg0);\n return ret;\n };\n imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {\n const ret = arg0.msCrypto;\n return ret;\n };\n imports.wbg.__wbg_new_8a6f238a6ece86ea = function() {\n const ret = new Error();\n return ret;\n };\n imports.wbg.__wbg_new_a12002a7f91c75be = function(arg0) {\n const ret = new Uint8Array(arg0);\n return ret;\n };\n imports.wbg.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) {\n const ret = new Function(getStringFromWasm0(arg0, arg1));\n return ret;\n };\n imports.wbg.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) {\n const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_newwithlength_a381634e90c276d4 = function(arg0) {\n const ret = new Uint8Array(arg0 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {\n const ret = arg0.node;\n return ret;\n };\n imports.wbg.__wbg_now_807e54c39636c349 = function() {\n const ret = Date.now();\n return ret;\n };\n imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {\n const ret = arg0.process;\n return ret;\n };\n imports.wbg.__wbg_proposalmessage_new = function(arg0) {\n const ret = ProposalMessage.__wrap(arg0);\n return ret;\n };\n imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {\n arg0.randomFillSync(arg1);\n }, arguments) };\n imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {\n const ret = module.require;\n return ret;\n }, arguments) };\n imports.wbg.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) {\n arg0.set(arg1, arg2 >>> 0);\n };\n imports.wbg.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {\n const ret = arg1.stack;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() {\n const ret = typeof global === 'undefined' ? null : global;\n return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() {\n const ret = typeof globalThis === 'undefined' ? null : globalThis;\n return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);\n };\n imports.wbg.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() {\n const ret = typeof self === 'undefined' ? null : self;\n return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);\n };\n imports.wbg.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() {\n const ret = typeof window === 'undefined' ? null : window;\n return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);\n };\n imports.wbg.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n };\n imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {\n const ret = arg0.versions;\n return ret;\n };\n imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {\n const ret = debugString(arg1);\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbindgen_error_new = function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return ret;\n };\n imports.wbg.__wbindgen_init_externref_table = function() {\n const table = wasm.__wbindgen_export_2;\n const offset = table.grow(4);\n table.set(0, undefined);\n table.set(offset + 0, undefined);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n ;\n };\n imports.wbg.__wbindgen_is_function = function(arg0) {\n const ret = typeof(arg0) === 'function';\n return ret;\n };\n imports.wbg.__wbindgen_is_object = function(arg0) {\n const val = arg0;\n const ret = typeof(val) === 'object' && val !== null;\n return ret;\n };\n imports.wbg.__wbindgen_is_string = function(arg0) {\n const ret = typeof(arg0) === 'string';\n return ret;\n };\n imports.wbg.__wbindgen_is_undefined = function(arg0) {\n const ret = arg0 === undefined;\n return ret;\n };\n imports.wbg.__wbindgen_memory = function() {\n const ret = wasm.memory;\n return ret;\n };\n imports.wbg.__wbindgen_string_get = function(arg0, arg1) {\n const obj = arg1;\n const ret = typeof(obj) === 'string' ? obj : undefined;\n var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbindgen_string_new = function(arg0, arg1) {\n const ret = getStringFromWasm0(arg0, arg1);\n return ret;\n };\n imports.wbg.__wbindgen_throw = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n\n return imports;\n}\n\nfunction __wbg_init_memory(imports, memory) {\n\n}\n\nfunction __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n __wbg_init.__wbindgen_wasm_module = module;\n cachedDataViewMemory0 = null;\n cachedUint32ArrayMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n\n\n wasm.__wbindgen_start();\n return wasm;\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module !== 'undefined') {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n globalThis.__ermisSdkLog?.('warn', 'using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n\n __wbg_init_memory(imports);\n\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n\n const instance = new WebAssembly.Instance(module, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module_or_path !== 'undefined') {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n globalThis.__ermisSdkLog?.('warn', 'using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n if (typeof module_or_path === 'undefined') {\n module_or_path = new URL('openmls_wasm_bg.wasm', import.meta.url);\n }\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n __wbg_init_memory(imports);\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync };\nexport default __wbg_init;\n","export * from './types';\nexport * from './api';\nexport * from './storage';\nexport * from './manager';\nexport * from './openmls';\nexport * from './aad';\nexport * from './attachments';\nexport * from './e2ee_media_mp4_probe';\nexport * from './e2ee_media_stream';\nexport * from './e2ee_media_stream_planner';\nexport * from './attachment_crypto_provider';\nexport * from './sha256';\n\nexport { E2eeClient as EncryptionApiClient } from './api';\nexport { EncryptionManager } from './manager';\nexport { IndexedDBEncryptionStorage as BrowserEncryptionStorage } from './storage';\n","const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst BASE64_LOOKUP = (() => {\n const lookup = new Int16Array(256);\n lookup.fill(-1);\n for (let i = 0; i < BASE64_ALPHABET.length; i += 1) {\n lookup[BASE64_ALPHABET.charCodeAt(i)] = i;\n }\n return lookup;\n})();\n\nconst ENCRYPTION_CHANNEL_BYTE_FIELDS = ['commit', 'welcome', 'ratchet_tree', 'group_info'] as const;\nconst PROTOCOL_BYTE_FIELDS = ['commit', 'welcome', 'ratchet_tree', 'proposal'] as const;\n\nexport const E2EE_BYTES_HEADER = 'X-Ermis-E2EE-Bytes';\nexport const E2EE_BYTES_WIRE_FORMAT = 'base64';\nexport const E2EE_BYTES_WS_QUERY_PARAM = 'e2ee_bytes';\n\nexport function encodeBytesToBase64(bytes: Uint8Array): string {\n if (!(bytes instanceof Uint8Array)) {\n throw new TypeError('expected Uint8Array');\n }\n\n let output = '';\n let i = 0;\n for (; i + 2 < bytes.length; i += 3) {\n const value = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];\n output += BASE64_ALPHABET[(value >> 18) & 0x3f];\n output += BASE64_ALPHABET[(value >> 12) & 0x3f];\n output += BASE64_ALPHABET[(value >> 6) & 0x3f];\n output += BASE64_ALPHABET[value & 0x3f];\n }\n\n const remaining = bytes.length - i;\n if (remaining === 1) {\n const value = bytes[i] << 16;\n output += BASE64_ALPHABET[(value >> 18) & 0x3f];\n output += BASE64_ALPHABET[(value >> 12) & 0x3f];\n output += '==';\n } else if (remaining === 2) {\n const value = (bytes[i] << 16) | (bytes[i + 1] << 8);\n output += BASE64_ALPHABET[(value >> 18) & 0x3f];\n output += BASE64_ALPHABET[(value >> 12) & 0x3f];\n output += BASE64_ALPHABET[(value >> 6) & 0x3f];\n output += '=';\n }\n\n return output;\n}\n\nexport function decodeBase64ToBytes(base64: string): Uint8Array {\n if (typeof base64 !== 'string') {\n throw new TypeError('expected base64 string');\n }\n if (base64.length % 4 !== 0) {\n throw new Error('invalid standard base64 length');\n }\n if (/[^A-Za-z0-9+/=]/.test(base64)) {\n throw new Error('invalid standard base64 character');\n }\n const firstPad = base64.indexOf('=');\n if (firstPad !== -1 && firstPad < base64.length - (base64.endsWith('==') ? 2 : 1)) {\n throw new Error('invalid standard base64 padding');\n }\n\n const padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0;\n const output = new Uint8Array((base64.length / 4) * 3 - padding);\n let outputIndex = 0;\n\n for (let i = 0; i < base64.length; i += 4) {\n const a = lookupBase64(base64.charCodeAt(i));\n const b = lookupBase64(base64.charCodeAt(i + 1));\n const c = base64[i + 2] === '=' ? 0 : lookupBase64(base64.charCodeAt(i + 2));\n const d = base64[i + 3] === '=' ? 0 : lookupBase64(base64.charCodeAt(i + 3));\n const value = (a << 18) | (b << 12) | (c << 6) | d;\n\n if (outputIndex < output.length) output[outputIndex++] = (value >> 16) & 0xff;\n if (outputIndex < output.length) output[outputIndex++] = (value >> 8) & 0xff;\n if (outputIndex < output.length) output[outputIndex++] = value & 0xff;\n }\n\n if (encodeBytesToBase64(output) !== base64) {\n throw new Error('non-canonical standard base64');\n }\n\n return output;\n}\n\nexport function normalizeRequiredBytes(value: unknown, fieldName = 'bytes'): Uint8Array {\n const normalized = normalizeOptionalBytes(value, fieldName);\n if (!normalized) {\n throw new TypeError(`${fieldName} is required`);\n }\n return normalized;\n}\n\nexport function normalizeOptionalBytes(value: unknown, fieldName = 'bytes'): Uint8Array | undefined {\n if (value == null) return undefined;\n if (value instanceof Uint8Array) return value;\n if (typeof value === 'string') return decodeBase64ToBytes(value);\n if (Array.isArray(value)) {\n const bytes = new Uint8Array(value.length);\n for (let i = 0; i < value.length; i += 1) {\n const byte = value[i];\n if (!Number.isInteger(byte) || byte < 0 || byte > 255) {\n throw new TypeError(`${fieldName} contains invalid byte at index ${i}`);\n }\n bytes[i] = byte;\n }\n return bytes;\n }\n throw new TypeError(`${fieldName} must be Uint8Array, base64 string, or legacy byte array`);\n}\n\nexport function encodeEncryptionChannelFields<T extends Record<string, unknown>>(input: T): T {\n const output: Record<string, unknown> = { ...input };\n for (const field of ENCRYPTION_CHANNEL_BYTE_FIELDS) {\n if (isByteLike(output[field])) {\n output[field] = encodeBytesToBase64(normalizeRequiredBytes(output[field], field));\n }\n }\n return output as T;\n}\n\nexport function normalizeE2eeEventBytes<T>(event: T): T {\n const value = event as Record<string, unknown>;\n\n normalizeMessageRecord(value.message as Record<string, unknown> | undefined);\n normalizeProtocolRecord(value.protocol_data as Record<string, unknown> | undefined);\n normalizeProtocolRecord(value.message as Record<string, unknown> | undefined);\n normalizeProtocolRecord(value);\n normalizeKeyPackageRef(value);\n normalizeKeyPackageRef(value.data as Record<string, unknown> | undefined);\n\n return event;\n}\n\nexport function normalizeE2eeSyncEventBytes<T>(event: T): T {\n const value = event as Record<string, unknown>;\n const data = value.data as Record<string, unknown> | undefined;\n if (!data) return event;\n\n if (value.type === 'application') {\n normalizeMessageRecord(data);\n } else if (value.type === 'protocol') {\n normalizeProtocolRecord(data);\n } else if (value.type === 'message_updated' || value.type === 'message_pin') {\n normalizeMessageRecord(data.message as Record<string, unknown> | undefined);\n }\n\n return event;\n}\n\nexport function normalizeScopeSyncResponseBytes<T>(response: T): T {\n const value = response as Record<string, unknown>;\n const channels = value.channels as Record<string, { events?: unknown[] }> | undefined;\n if (!channels) return response;\n\n for (const result of Object.values(channels)) {\n if (!Array.isArray(result?.events)) continue;\n for (const event of result.events) {\n const syncEvent = event as Record<string, unknown>;\n const data = syncEvent.data as Record<string, unknown> | undefined;\n if (!data) continue;\n if (syncEvent.type === 'application') {\n normalizeMessageRecord(data);\n } else if (syncEvent.type === 'protocol') {\n normalizeProtocolRecord(data);\n } else if (syncEvent.type === 'message_updated' || syncEvent.type === 'message_pin') {\n normalizeMessageRecord(data.message as Record<string, unknown> | undefined);\n }\n }\n }\n\n return response;\n}\n\nfunction normalizeMessageRecord(record?: Record<string, unknown>): void {\n if (!record || record.mls_ciphertext == null) return;\n record.mls_ciphertext = normalizeRequiredBytes(record.mls_ciphertext, 'mls_ciphertext');\n}\n\nfunction normalizeProtocolRecord(record?: Record<string, unknown>): void {\n if (!record) return;\n for (const field of PROTOCOL_BYTE_FIELDS) {\n if (record[field] != null) {\n record[field] = normalizeRequiredBytes(record[field], field);\n }\n }\n}\n\nfunction normalizeKeyPackageRef(record?: Record<string, unknown>): void {\n if (!record || record.key_package_ref == null) return;\n record.key_package_ref = normalizeRequiredBytes(record.key_package_ref, 'key_package_ref');\n}\n\nfunction lookupBase64(code: number): number {\n const value = BASE64_LOOKUP[code];\n if (value < 0) {\n throw new Error('invalid standard base64 character');\n }\n return value;\n}\n\nfunction isByteLike(value: unknown): boolean {\n if (value instanceof Uint8Array) return true;\n return Array.isArray(value) && value.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255);\n}\n","/**\n * E2EE (encryption) API methods for Ermis Chat\n *\n * All endpoints are under `/v1/e2ee/` and require JWT auth.\n * WASM module (openmls-wasm) handles the cryptographic operations client-side.\n */\n\nimport type { ErmisChat } from '../client';\nimport {\n E2EE_BYTES_HEADER,\n E2EE_BYTES_WIRE_FORMAT,\n encodeBytesToBase64,\n normalizeE2eeSyncEventBytes,\n normalizeRequiredBytes,\n normalizeScopeSyncResponseBytes,\n} from './encoding';\nimport type { APIResponse, ExtendableGenerics, DefaultGenerics } from '../types';\nimport type {\n ArchiveBlobRecord,\n ArchiveKeyWrapRecord,\n BatchAddMembersToTopicsRequest,\n BatchExternalJoinTopicsRequest,\n BatchTopicResponse,\n ChannelSyncResult,\n CiphertextCursor,\n CiphertextQueryResponse,\n CommitEvictionRequest,\n CommitEvictionResponse,\n DeviceKeyPackage,\n E2eeSyncEvent,\n EnableE2eeRequest,\n ExternalJoinRequest,\n GetGroupInfoResponse,\n GetKeyPackagesByCidResponse,\n GetKeyPackagesResponse,\n HistoricalCiphertext,\n CompleteE2eeAttachmentRequest,\n CompleteE2eeAttachmentResponse,\n DeleteE2eeAttachmentResponse,\n DownloadE2eeAttachmentGrantResponse,\n InitE2eeAttachmentRequest,\n InitE2eeAttachmentResponse,\n KeyPackageCountResponse,\n KeyRotationRequest,\n ListArchiveAvailabilityResponse,\n MemberKeyPackages,\n MemberSnapshotRecord,\n EncryptionOperationResponse,\n QueryArchiveMaterialRequest,\n QueryEpochArchivesRequest,\n QueryEpochArchivesResponse,\n QueryE2eeAttachmentsRequest,\n QueryE2eeAttachmentsResponse,\n QuerySponsoredArchiveRecipientsResponse,\n RecoveryPublicKeyResponse,\n RecoveryVaultResponse,\n RemovedChannelsSyncResult,\n ScopeSyncResponse,\n SendE2eeMessageRequest,\n SponsoredArchiveRecipient,\n UnifiedSyncResponse,\n UpdateE2eeMessageRequest,\n UploadEpochArchiveRequest,\n UploadEpochArchiveResponse,\n UploadGroupInfoRequest,\n UploadKeyPackagesRequest,\n UploadKeyPackagesResponse,\n UploadRecoveryVaultRequest,\n UploadRecoveryVaultResponse,\n EventCursor,\n RemovedSyncCursor,\n} from './types';\n\n// ============================================================\n// E2EE API Client\n// ============================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyClient = any;\ntype Base64Bytes = string;\ntype RawDeviceKeyPackage = Omit<DeviceKeyPackage, 'key_package'> & { key_package: Base64Bytes };\ntype RawMemberKeyPackages = Omit<MemberKeyPackages, 'key_packages'> & { key_packages: RawDeviceKeyPackage[] };\ntype RawGetKeyPackagesResponse = Omit<GetKeyPackagesResponse, 'key_packages'> & { key_packages: RawDeviceKeyPackage[] };\ntype RawGetKeyPackagesByCidResponse = Omit<GetKeyPackagesByCidResponse, 'members'> & {\n members: RawMemberKeyPackages[];\n};\ntype RawGetGroupInfoResponse = Omit<GetGroupInfoResponse, 'group_info'> & { group_info: Base64Bytes };\ntype RawRecoveryVaultResponse = Omit<RecoveryVaultResponse, 'vault_bytes'> & { vault_bytes: Base64Bytes };\ntype RawRecoveryPublicKeyResponse = Omit<RecoveryPublicKeyResponse, 'public_key'> & { public_key: Base64Bytes };\ntype RawArchiveBlobRecord = Omit<ArchiveBlobRecord, 'encrypted_archive_bytes' | 'aead_nonce' | 'aead_aad'> & {\n encrypted_archive_bytes: Base64Bytes;\n aead_nonce: Base64Bytes;\n aead_aad: Base64Bytes;\n};\ntype RawArchiveKeyWrapRecord = Omit<ArchiveKeyWrapRecord, 'hpke_kem_output' | 'hpke_ciphertext' | 'hpke_info'> & {\n hpke_kem_output: Base64Bytes;\n hpke_ciphertext: Base64Bytes;\n hpke_info: Base64Bytes;\n};\ntype RawMemberSnapshotRecord = Omit<MemberSnapshotRecord, 'snapshot_bytes'> & { snapshot_bytes: Base64Bytes };\ntype RawQueryEpochArchivesResponse = Omit<QueryEpochArchivesResponse, 'blobs' | 'wraps' | 'snapshots'> & {\n blobs?: RawArchiveBlobRecord[];\n wraps?: RawArchiveKeyWrapRecord[];\n snapshots?: Record<string, RawMemberSnapshotRecord>;\n};\n\ntype RawSponsoredArchiveRecipient = Omit<SponsoredArchiveRecipient, 'public_key'> & { public_key: unknown };\ntype RawQuerySponsoredArchiveRecipientsResponse = Omit<QuerySponsoredArchiveRecipientsResponse, 'recipients'> & {\n recipients: RawSponsoredArchiveRecipient[];\n};\ntype RawHistoricalCiphertext = Omit<HistoricalCiphertext, 'mls_ciphertext'> & { mls_ciphertext: Base64Bytes };\ntype RawCiphertextQueryResponse = Omit<CiphertextQueryResponse, 'ciphertexts'> & {\n ciphertexts: RawHistoricalCiphertext[];\n};\n\nfunction encodeBytesField(bytes: Uint8Array, fieldName: string): Base64Bytes {\n return encodeBytesToBase64(normalizeRequiredBytes(bytes, fieldName));\n}\n\nfunction decodeBytesField(bytes: unknown, fieldName: string): Uint8Array {\n return normalizeRequiredBytes(bytes, fieldName);\n}\n\nfunction encodeKeyRotationRequest(data: KeyRotationRequest): Record<string, unknown> {\n return {\n ...data,\n commit: encodeBytesField(data.commit, 'commit'),\n group_info: encodeBytesField(data.group_info, 'group_info'),\n };\n}\n\nfunction encodeEnableE2eeRequest(data: EnableE2eeRequest): Record<string, unknown> {\n return {\n ...data,\n ...(data.commit ? { commit: encodeBytesField(data.commit, 'commit') } : {}),\n welcome: encodeBytesField(data.welcome, 'welcome'),\n ratchet_tree: encodeBytesField(data.ratchet_tree, 'ratchet_tree'),\n group_info: encodeBytesField(data.group_info, 'group_info'),\n };\n}\n\nfunction encodeGroupInfoRequest(data: UploadGroupInfoRequest): Record<string, unknown> {\n return { ...data, group_info: encodeBytesField(data.group_info, 'group_info') };\n}\n\nfunction encodeExternalJoinRequest(data: ExternalJoinRequest): Record<string, unknown> {\n return {\n ...data,\n commit: encodeBytesField(data.commit, 'commit'),\n ...(data.group_info ? { group_info: encodeBytesField(data.group_info, 'group_info') } : {}),\n };\n}\n\nfunction encodeCommitEvictionRequest(data: CommitEvictionRequest): Record<string, unknown> {\n return {\n ...data,\n commit: encodeBytesField(data.commit, 'commit'),\n group_info: encodeBytesField(data.group_info, 'group_info'),\n };\n}\n\nfunction encodeSendMessageRequest(data: SendE2eeMessageRequest): Record<string, unknown> {\n return {\n ...data,\n message: {\n ...data.message,\n mls_ciphertext: encodeBytesField(data.message.mls_ciphertext, 'mls_ciphertext'),\n },\n };\n}\n\nfunction encodeUpdateMessageRequest(data: UpdateE2eeMessageRequest): Record<string, unknown> {\n return {\n ...data,\n message: {\n ...data.message,\n mls_ciphertext: encodeBytesField(data.message.mls_ciphertext, 'mls_ciphertext'),\n },\n };\n}\n\nfunction encodeArchiveUploadRequest(data: UploadEpochArchiveRequest): Record<string, unknown> {\n return {\n ...data,\n encrypted_archive: {\n ciphertext: encodeBytesField(data.encrypted_archive.ciphertext, 'encrypted_archive.ciphertext'),\n nonce: encodeBytesField(data.encrypted_archive.nonce, 'encrypted_archive.nonce'),\n aead_aad: encodeBytesField(data.encrypted_archive.aead_aad, 'encrypted_archive.aead_aad'),\n },\n snapshot: {\n ...data.snapshot,\n snapshot_bytes: encodeBytesField(data.snapshot.snapshot_bytes, 'snapshot.snapshot_bytes'),\n },\n wraps: data.wraps.map((wrap) => ({\n ...wrap,\n hpke_kem_output: encodeBytesField(wrap.hpke_kem_output, 'wrap.hpke_kem_output'),\n hpke_ciphertext: encodeBytesField(wrap.hpke_ciphertext, 'wrap.hpke_ciphertext'),\n hpke_info: encodeBytesField(wrap.hpke_info, 'wrap.hpke_info'),\n })),\n };\n}\n\nfunction encodeBatchAddMembersToTopicsRequest(data: BatchAddMembersToTopicsRequest): Record<string, unknown> {\n return {\n ...data,\n topics: data.topics.map((topic) => ({\n ...topic,\n commit: encodeBytesField(topic.commit, 'topic.commit'),\n welcome: encodeBytesField(topic.welcome, 'topic.welcome'),\n ratchet_tree: encodeBytesField(topic.ratchet_tree, 'topic.ratchet_tree'),\n group_info: encodeBytesField(topic.group_info, 'topic.group_info'),\n })),\n };\n}\n\nfunction encodeBatchExternalJoinTopicsRequest(data: BatchExternalJoinTopicsRequest): Record<string, unknown> {\n return {\n ...data,\n topics: data.topics.map((topic) => ({\n ...topic,\n commit: encodeBytesField(topic.commit, 'topic.commit'),\n ...(topic.group_info ? { group_info: encodeBytesField(topic.group_info, 'topic.group_info') } : {}),\n })),\n };\n}\n\nfunction decodeDeviceKeyPackage(raw: RawDeviceKeyPackage): DeviceKeyPackage {\n return { ...raw, key_package: decodeBytesField(raw.key_package, 'key_package') };\n}\n\nfunction decodeKeyPackagesByCidResponse(raw: RawGetKeyPackagesByCidResponse): GetKeyPackagesByCidResponse {\n return {\n ...raw,\n members: raw.members.map((member) => ({\n ...member,\n key_packages: member.key_packages.map(decodeDeviceKeyPackage),\n })),\n };\n}\n\nfunction decodeArchiveBlob(raw: RawArchiveBlobRecord): ArchiveBlobRecord {\n return {\n ...raw,\n encrypted_archive_bytes: decodeBytesField(raw.encrypted_archive_bytes, 'encrypted_archive_bytes'),\n aead_nonce: decodeBytesField(raw.aead_nonce, 'aead_nonce'),\n aead_aad: decodeBytesField(raw.aead_aad, 'aead_aad'),\n };\n}\n\nfunction decodeArchiveKeyWrap(raw: RawArchiveKeyWrapRecord): ArchiveKeyWrapRecord {\n return {\n ...raw,\n hpke_kem_output: decodeBytesField(raw.hpke_kem_output, 'hpke_kem_output'),\n hpke_ciphertext: decodeBytesField(raw.hpke_ciphertext, 'hpke_ciphertext'),\n hpke_info: decodeBytesField(raw.hpke_info, 'hpke_info'),\n };\n}\n\nfunction decodeMemberSnapshot(raw: RawMemberSnapshotRecord): MemberSnapshotRecord {\n return { ...raw, snapshot_bytes: decodeBytesField(raw.snapshot_bytes, 'snapshot_bytes') };\n}\n\n/**\n * E2EE API wrapper — instantiate via `new E2eeClient(ermisChatClient)`\n *\n * @example\n * ```ts\n * const e2ee = new E2eeClient(chatClient);\n * await e2ee.uploadKeyPackages({ key_packages: [kpBytes1, kpBytes2] });\n * ```\n */\nexport class E2eeClient<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n private client: AnyClient;\n\n constructor(client: ErmisChat<ErmisChatGenerics>) {\n this.client = client;\n }\n\n private get baseURL(): string {\n return this.client.baseURL;\n }\n\n /** Build headers with X-Device-ID if available */\n private get deviceHeaders(): Record<string, string> {\n const deviceId = (this.client as any).deviceId;\n return {\n [E2EE_BYTES_HEADER]: E2EE_BYTES_WIRE_FORMAT,\n ...(deviceId ? { 'X-Device-ID': deviceId } : {}),\n };\n }\n\n /** POST with X-Device-ID header */\n private async _post<T>(url: string, data?: unknown, headers?: Record<string, string>): Promise<T> {\n return await (this.client as any).doAxiosRequest('post', url, data, {\n headers: { ...this.deviceHeaders, ...(headers || {}) },\n });\n }\n\n /** GET with X-Device-ID header */\n private async _get<T>(url: string, params?: Record<string, unknown>): Promise<T> {\n return await (this.client as any).doAxiosRequest('get', url, null, {\n params: params || {},\n headers: this.deviceHeaders,\n });\n }\n\n /** DELETE with X-Device-ID header */\n private async _delete<T>(url: string): Promise<T> {\n return await (this.client as any).doAxiosRequest('delete', url, null, {\n headers: this.deviceHeaders,\n });\n }\n\n // ---- KeyPackage Management ----\n\n /** Upload TLS-serialized KeyPackages for the current device. Requires `X-Device-ID` header. */\n async uploadKeyPackages(data: UploadKeyPackagesRequest): Promise<UploadKeyPackagesResponse> {\n return await this._post(this.baseURL + '/v1/e2ee/key_packages', {\n key_packages: data.key_packages.map((kp) => encodeBytesField(kp, 'key_package')),\n });\n }\n\n /** Check remaining KeyPackage count for the current user. */\n async getKeyPackageCount(): Promise<KeyPackageCountResponse> {\n return await this._get(this.baseURL + '/v1/e2ee/key_packages/count');\n }\n\n /** Consume one KeyPackage per device of the target user. */\n async getKeyPackages(targetUserId: string): Promise<GetKeyPackagesResponse> {\n const raw = await this._get<RawGetKeyPackagesResponse>(this.baseURL + `/v1/e2ee/key_packages/${targetUserId}`);\n return {\n ...raw,\n key_packages: raw.key_packages.map(decodeDeviceKeyPackage),\n };\n }\n\n /**\n * Consume one KeyPackage per device for channel members.\n * Always excludes the sender (caller). Optionally filter by specific user IDs.\n *\n * @param channelType - e.g. \"messaging\"\n * @param channelId - channel ID\n * @param targetUserIds - optional: only fetch KPs for these users (for add_members).\n * If omitted, returns KPs for ALL members except sender (for enable E2EE).\n */\n async getKeyPackagesByCid(\n channelType: string,\n channelId: string,\n targetUserIds?: string[],\n ): Promise<GetKeyPackagesByCidResponse> {\n const raw = await this._post<RawGetKeyPackagesByCidResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/key_packages`,\n {\n target_user_ids: targetUserIds,\n },\n );\n return decodeKeyPackagesByCidResponse(raw);\n }\n\n /**\n * Fetch and consume one KeyPackage per device for a list of user IDs.\n * Does NOT require a channel to exist — use this when creating a new E2EE channel.\n * Sender is auto-excluded server-side (also skipped if listed explicitly).\n *\n * @param userIds - List of user IDs to fetch KPs for (sender will be excluded server-side)\n */\n async getKeyPackagesByUserIds(userIds: string[], countPerDevice?: number): Promise<GetKeyPackagesByCidResponse> {\n const raw = await this._post<RawGetKeyPackagesByCidResponse>(this.baseURL + '/v1/e2ee/key_packages/batch', {\n user_ids: userIds,\n ...(countPerDevice && countPerDevice > 1 ? { count_per_device: countPerDevice } : {}),\n });\n return decodeKeyPackagesByCidResponse(raw);\n }\n\n // ---- Recovery Vault ----\n\n async uploadRecoveryVault(data: UploadRecoveryVaultRequest): Promise<UploadRecoveryVaultResponse> {\n return await this._post<UploadRecoveryVaultResponse>(this.baseURL + '/v1/e2ee/recovery/vault', {\n vault_bytes: encodeBytesField(data.vault_bytes, 'vault_bytes'),\n ...(data.expected_revision !== undefined ? { expected_revision: data.expected_revision } : {}),\n });\n }\n\n async getRecoveryVault(): Promise<RecoveryVaultResponse> {\n const raw = await this._get<RawRecoveryVaultResponse>(this.baseURL + '/v1/e2ee/recovery/vault');\n return { ...raw, vault_bytes: decodeBytesField(raw.vault_bytes, 'vault_bytes') };\n }\n\n async getRecoveryPublicKey(userId: string): Promise<RecoveryPublicKeyResponse> {\n const raw = await this._get<RawRecoveryPublicKeyResponse>(this.baseURL + `/v1/e2ee/recovery/public_key/${userId}`);\n return { ...raw, public_key: decodeBytesField(raw.public_key, 'public_key') };\n }\n\n // ---- Epoch Archives ----\n\n async uploadEpochArchive(\n channelType: string,\n channelId: string,\n data: UploadEpochArchiveRequest,\n ): Promise<UploadEpochArchiveResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives`,\n encodeArchiveUploadRequest(data),\n );\n }\n\n async querySponsoredArchiveRecipients(\n channelType: string,\n channelId: string,\n epoch: number,\n ): Promise<QuerySponsoredArchiveRecipientsResponse> {\n const raw = await this._post<RawQuerySponsoredArchiveRecipientsResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/recipients/query`,\n { epoch },\n );\n return {\n ...raw,\n recipients: raw.recipients.map((recipient) => ({\n ...recipient,\n public_key: decodeBytesField(recipient.public_key, 'recipient.public_key'),\n })),\n };\n }\n\n async queryEpochArchives(\n channelType: string,\n channelId: string,\n data: QueryEpochArchivesRequest,\n ): Promise<QueryEpochArchivesResponse> {\n const raw = await this._post<RawQueryEpochArchivesResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/query`,\n data,\n );\n return {\n ...raw,\n blobs: raw.blobs?.map(decodeArchiveBlob),\n wraps: raw.wraps?.map(decodeArchiveKeyWrap),\n snapshots: raw.snapshots\n ? Object.fromEntries(\n Object.entries(raw.snapshots).map(([hash, snapshot]) => [hash, decodeMemberSnapshot(snapshot)]),\n )\n : undefined,\n };\n }\n\n async listArchiveAvailability(\n channelType: string,\n channelId: string,\n data: { cursor?: string; limit?: number } = {},\n ): Promise<ListArchiveAvailabilityResponse> {\n return await this._post<ListArchiveAvailabilityResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/availability/query`,\n data,\n );\n }\n\n async queryArchiveMaterial(\n channelType: string,\n channelId: string,\n data: QueryArchiveMaterialRequest,\n ): Promise<QueryEpochArchivesResponse> {\n const raw = await this._post<RawQueryEpochArchivesResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/material/query`,\n data,\n );\n return {\n ...raw,\n blobs: raw.blobs?.map(decodeArchiveBlob),\n wraps: raw.wraps?.map(decodeArchiveKeyWrap),\n snapshots: raw.snapshots\n ? Object.fromEntries(\n Object.entries(raw.snapshots).map(([hash, snapshot]) => [hash, decodeMemberSnapshot(snapshot)]),\n )\n : undefined,\n };\n }\n\n async getArchiveSnapshot(channelType: string, channelId: string, hash: string): Promise<MemberSnapshotRecord> {\n const raw = await this._get<RawMemberSnapshotRecord>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/snapshot/${hash}`,\n );\n return decodeMemberSnapshot(raw);\n }\n\n async queryArchiveCiphertexts(\n channelType: string,\n channelId: string,\n data: { epoch_from: number; epoch_to: number; cursor?: CiphertextCursor; limit?: number },\n ): Promise<CiphertextQueryResponse> {\n const raw = await this._post<RawCiphertextQueryResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/epoch_archives/ciphertexts/query`,\n data,\n );\n return {\n ...raw,\n ciphertexts: raw.ciphertexts.map((ciphertext) => ({\n ...ciphertext,\n mls_ciphertext: decodeBytesField(ciphertext.mls_ciphertext, 'mls_ciphertext'),\n })),\n };\n }\n\n // ---- Enable E2EE ----\n\n /** Upgrade a standard channel to E2EE. Admin or channel Owner only. All members must have accepted their invites. */\n async enableE2ee(\n channelType: string,\n channelId: string,\n data: EnableE2eeRequest,\n ): Promise<EncryptionOperationResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/enable`,\n encodeEnableE2eeRequest(data),\n );\n }\n\n // NOTE: addMembers has been removed — add_members is now handled through\n // the standard edit_channel endpoint (POST /channels/{type}/{id}).\n // See EncryptionManager.addMembers() in encryption/manager.ts for the updated flow.\n\n // removeMember — REMOVED\n // Merged into edit_channel_handler (RemoveMembers branch).\n // Use channel.removeMembersE2ee() which calls the standard POST /channels/{type}/{id} endpoint.\n // See EncryptionManager.evictMember() in encryption/manager.ts for the updated flow.\n\n /** Key rotation (self update): rotate own key material for forward secrecy. */\n async keyRotation(\n channelType: string,\n channelId: string,\n data: KeyRotationRequest,\n ): Promise<EncryptionOperationResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/key_rotation`,\n encodeKeyRotationRequest(data),\n );\n }\n\n // ---- E2EE Messaging & Sync ----\n\n /** Send an encrypted E2EE message. */\n async sendMessage(channelType: string, channelId: string, data: SendE2eeMessageRequest): Promise<APIResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/message`,\n encodeSendMessageRequest(data),\n );\n }\n\n /** Initialize E2EE attachment upload and receive presigned PUT URLs. */\n async initAttachment(\n channelType: string,\n channelId: string,\n data: InitE2eeAttachmentRequest,\n options: { multipart?: boolean } = {},\n ): Promise<InitE2eeAttachmentResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/attachments/init`,\n data,\n options.multipart ? { 'X-Ermis-E2EE-Attachment-Upload': 'multipart-v1' } : undefined,\n );\n }\n\n /** Query confirmed E2EE attachment projections for Channel Info media/files tabs. */\n async queryE2eeAttachments(\n channelType: string,\n channelId: string,\n data: QueryE2eeAttachmentsRequest = {},\n ): Promise<QueryE2eeAttachmentsResponse> {\n return await this._post(this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/attachments/query`, data);\n }\n\n /** Complete an E2EE attachment after direct object upload. */\n async completeAttachment(\n channelType: string,\n channelId: string,\n attachmentId: string,\n data: CompleteE2eeAttachmentRequest,\n ): Promise<CompleteE2eeAttachmentResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/attachments/${attachmentId}/complete`,\n data,\n );\n }\n\n /** Request a presigned GET URL for a confirmed E2EE attachment asset. */\n async downloadAttachmentGrant(\n channelType: string,\n channelId: string,\n attachmentId: string,\n assetId: string,\n ): Promise<DownloadE2eeAttachmentGrantResponse> {\n return await this._post(\n this.baseURL +\n `/v1/e2ee/channels/${channelType}/${channelId}/attachments/${attachmentId}/assets/${assetId}/download-grant`,\n {},\n );\n }\n\n /** Cancel an unbound E2EE attachment. */\n async deleteAttachment(\n channelType: string,\n channelId: string,\n attachmentId: string,\n ): Promise<DeleteE2eeAttachmentResponse> {\n return await this._delete(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/attachments/${attachmentId}`,\n );\n }\n\n /** Update an encrypted E2EE message snapshot. */\n async updateMessage(\n channelType: string,\n channelId: string,\n messageId: string,\n data: UpdateE2eeMessageRequest,\n ): Promise<APIResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/${messageId}`,\n encodeUpdateMessageRequest(data),\n );\n }\n\n /**\n * Per-channel sync: fetch protocol + application events for a single channel.\n * @param since RFC3339 timestamp cursor\n * @param limit Max events to return (default 100, server caps at 200)\n */\n async syncChannel(\n channelType: string,\n channelId: string,\n since: string,\n limit: number = 100,\n ): Promise<ChannelSyncResult> {\n const raw = await this._get<ChannelSyncResult>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/sync`,\n {\n since,\n limit,\n },\n );\n raw.events = raw.events.map(normalizeE2eeSyncEventBytes);\n return raw;\n }\n\n /**\n * Unified sync: fetch all protocol + application events across multiple E2EE channels.\n * @param cursors Map of CID → last sync timestamp (RFC3339)\n * @param limit Max events per channel (default 100, server caps at 200)\n */\n async syncAll(\n cursors: Record<string, string>,\n limit: number = 100,\n removedCursor?: RemovedSyncCursor,\n ): Promise<UnifiedSyncResponse> {\n const body: { cursors: Record<string, string>; limit: number; removed_cursor?: RemovedSyncCursor } = {\n cursors,\n limit,\n };\n if (removedCursor !== undefined) {\n body.removed_cursor = removedCursor;\n }\n const raw = await this._post<UnifiedSyncResponse>(this.baseURL + '/v1/e2ee/sync', body);\n for (const value of Object.values(raw)) {\n const result = value as { events?: unknown[] } | undefined;\n if (result && 'events' in result && Array.isArray(result.events)) {\n result.events = result.events.map(normalizeE2eeSyncEventBytes);\n }\n }\n return raw;\n }\n\n /**\n * Scope sync: fetch ordered protocol, application, and metadata events for each E2EE scope.\n * Non-gated topics inherit their parent scope, so clients keep one composite cursor per scope.\n */\n async scopeSync(\n cursors: Record<string, EventCursor>,\n limit: number = 100,\n removedCursor?: RemovedSyncCursor | null,\n ): Promise<ScopeSyncResponse> {\n const body: {\n cursors: Record<string, EventCursor>;\n limit: number;\n removed_cursor?: RemovedSyncCursor | null;\n } = {\n cursors,\n limit,\n };\n if (removedCursor !== undefined) {\n body.removed_cursor = removedCursor;\n }\n const raw = await this._post<ScopeSyncResponse>(this.baseURL + '/v1/e2ee/scope_sync', body);\n return normalizeScopeSyncResponseBytes(raw);\n }\n\n // ============================================================\n // GroupInfo & External Join\n // ============================================================\n\n /**\n * Upload GroupInfo for a channel (UPSERT — overwrites old)\n * Called after every successful commit to enable External Join\n */\n async uploadGroupInfo(\n channelType: string,\n channelId: string,\n data: UploadGroupInfoRequest,\n ): Promise<EncryptionOperationResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/group_info`,\n encodeGroupInfoRequest(data),\n );\n }\n\n /**\n * Get GroupInfo for a channel (for External Join)\n * Multi-device: must be member. Public channel: anyone.\n */\n async getGroupInfo(channelType: string, channelId: string): Promise<GetGroupInfoResponse> {\n const raw = await this._get<RawGetGroupInfoResponse>(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/group_info`,\n );\n return { ...raw, group_info: decodeBytesField(raw.group_info, 'group_info') };\n }\n\n /**\n * Submit external join commit to server\n * Multi-device: only broadcast commit. Public channel: insert member + system msg + commit.\n */\n async externalJoin(\n channelType: string,\n channelId: string,\n data: ExternalJoinRequest,\n ): Promise<EncryptionOperationResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/external_join`,\n encodeExternalJoinRequest(data),\n );\n }\n\n /**\n * Commit the encryption eviction of a user who already self-left the channel.\n *\n * Called by the designated evictor (owner/moder) after receiving `member.removed`\n * triggered by a `self_remove=true` leave. The target user is already removed from\n * channel DB — this endpoint only processes the encryption commit (no membership check).\n *\n * `POST /v1/e2ee/channels/{type}/{id}/commit_eviction`\n */\n // ---- Batch Topic E2EE Operations ----\n\n /**\n * Batch add members to N E2EE topics at once.\n * Each topic has its own encryption bundle (commit + welcome + ratchet_tree + group_info + epoch).\n * Independent processing: one topic failure does NOT affect others.\n *\n * `POST /v1/e2ee/channels/{type}/{id}/topics/batch_add_members`\n */\n async batchAddMembersToTopics(\n channelType: string,\n channelId: string,\n data: BatchAddMembersToTopicsRequest,\n ): Promise<BatchTopicResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/topics/batch_add_members`,\n encodeBatchAddMembersToTopicsRequest(data),\n );\n }\n\n /**\n * Batch external join for N E2EE topics (multi-device).\n * Lightweight: only commit + epoch + optional group_info per topic.\n *\n * `POST /v1/e2ee/channels/{type}/{id}/topics/batch_external_join`\n */\n async batchExternalJoinTopics(\n channelType: string,\n channelId: string,\n data: BatchExternalJoinTopicsRequest,\n ): Promise<BatchTopicResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/topics/batch_external_join`,\n encodeBatchExternalJoinTopicsRequest(data),\n );\n }\n\n // ---- Eviction ----\n\n async commitEviction(\n channelType: string,\n channelId: string,\n data: CommitEvictionRequest,\n ): Promise<CommitEvictionResponse> {\n return await this._post(\n this.baseURL + `/v1/e2ee/channels/${channelType}/${channelId}/commit_eviction`,\n encodeCommitEvictionRequest(data),\n );\n }\n}\n","import FormData from 'form-data';\nimport { ExtendableGenerics, DefaultGenerics, MessageResponse, FormatMessageResponse, ForwardMessage } from './types';\nimport { AxiosRequestConfig } from 'axios';\nimport { ErmisChat } from './client';\nimport { sdkLog } from './logger';\n\n/**\n * logChatPromiseExecution - utility function for logging the execution of a promise..\n * use this when you want to run the promise and handle errors by logging a warning\n *\n * @param {Promise<T>} promise The promise you want to run and log\n * @param {string} name A descriptive name of what the promise does for log output\n *\n */\nexport function logChatPromiseExecution<T>(promise: Promise<T>, name: string) {\n promise.then().catch((error) => {\n sdkLog('warn', `failed to do ${name}, ran into error: `, error);\n });\n}\n\nexport const sleep = (m: number): Promise<void> => new Promise((r) => setTimeout(r, m));\n\nexport function isFunction<T>(value: Function | T): value is Function {\n return (\n value &&\n (Object.prototype.toString.call(value) === '[object Function]' ||\n 'function' === typeof value ||\n value instanceof Function)\n );\n}\n\nexport const chatCodes = {\n TOKEN_EXPIRED: 40,\n WS_CLOSED_SUCCESS: 1000,\n};\n\nfunction isReadableStream(obj: unknown): obj is NodeJS.ReadStream {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function')\n );\n}\n\nfunction isBuffer(obj: unknown): obj is Buffer {\n return (\n obj != null &&\n (obj as Buffer).constructor != null &&\n // @ts-expect-error\n typeof obj.constructor.isBuffer === 'function' &&\n // @ts-expect-error\n obj.constructor.isBuffer(obj)\n );\n}\n\nfunction isFileWebAPI(uri: unknown): uri is File {\n return typeof window !== 'undefined' && 'File' in window && uri instanceof File;\n}\n\nfunction isBlobWebAPI(uri: unknown): uri is Blob {\n return typeof window !== 'undefined' && 'Blob' in window && uri instanceof Blob;\n}\n\nexport function addFileToFormData(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n) {\n const data = new FormData();\n\n if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {\n if (name) data.append('file', uri, name);\n else data.append('file', uri);\n } else {\n data.append('file', {\n uri,\n name: name || (uri as string).split('/').reverse()[0],\n contentType: contentType || undefined,\n type: contentType || undefined,\n });\n }\n\n return data;\n}\n\n/**\n * retryInterval - A retry interval which increases acc to number of failures\n *\n * @return {number} Duration to wait in milliseconds\n */\nexport function retryInterval(numberOfFailures: number) {\n // try to reconnect in 0.25-25 seconds (random to spread out the load from failures)\n const max = Math.min(500 + numberOfFailures * 2000, 25000);\n const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2000), 25000);\n return Math.floor(Math.random() * (max - min) + min);\n}\n\nexport function randomId() {\n return generateUUIDv4();\n}\n\nfunction hex(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0');\n }\n return s;\n}\n\n// https://tools.ietf.org/html/rfc4122\nexport function generateUUIDv4() {\n const bytes = getRandomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant\n\n return (\n hex(bytes.subarray(0, 4)) +\n '-' +\n hex(bytes.subarray(4, 6)) +\n '-' +\n hex(bytes.subarray(6, 8)) +\n '-' +\n hex(bytes.subarray(8, 10)) +\n '-' +\n hex(bytes.subarray(10, 16))\n );\n}\n\nfunction getRandomValuesWithMathRandom(bytes: Uint8Array): void {\n const max = Math.pow(2, (8 * bytes.byteLength) / bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.random() * max;\n }\n}\ndeclare const msCrypto: Crypto;\n\nconst getRandomValues = (() => {\n if (typeof crypto !== 'undefined' && typeof crypto?.getRandomValues !== 'undefined') {\n return crypto.getRandomValues.bind(crypto);\n } else if (typeof msCrypto !== 'undefined') {\n return msCrypto.getRandomValues.bind(msCrypto);\n } else {\n return getRandomValuesWithMathRandom;\n }\n})();\n\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getRandomValues(bytes);\n return bytes;\n}\n\n/**\n * listenForConnectionChanges - Adds an event listener fired on browser going online or offline\n */\nexport function addConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('offline', cb);\n window.addEventListener('online', cb);\n }\n}\n\nexport function removeConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.removeEventListener) {\n window.removeEventListener('offline', cb);\n window.removeEventListener('online', cb);\n }\n}\n\nexport const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (params) => {\n const newParams = [];\n for (const k in params) {\n // Ermis backend doesn't treat \"undefined\" value same as value not being present.\n // So, we need to skip the undefined values.\n if (params[k] === undefined) continue;\n\n if (Array.isArray(params[k]) || typeof params[k] === 'object') {\n newParams.push(`${k}=${encodeURIComponent(JSON.stringify(params[k]))}`);\n } else {\n newParams.push(`${k}=${encodeURIComponent(params[k])}`);\n }\n }\n\n return newParams.join('&');\n};\n\n/**\n * formatMessage - Takes the message object. Parses the dates, sets __html\n * and sets the status to received if missing. Returns a message object\n *\n * @param {MessageResponse<ErmisChatGenerics>} message a message object\n *\n */\nexport function formatMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: MessageResponse<ErmisChatGenerics>,\n): FormatMessageResponse<ErmisChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the date..\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),\n status: message.status || 'received',\n };\n}\n\nexport function addToMessageList<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n messages: Array<FormatMessageResponse<ErmisChatGenerics>>,\n message: FormatMessageResponse<ErmisChatGenerics>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n) {\n const addMessageToList = addIfDoesNotExist || timestampChanged;\n let messageArr = messages;\n const mergeMessage = (\n existingMessage: FormatMessageResponse<ErmisChatGenerics>,\n incomingMessage: FormatMessageResponse<ErmisChatGenerics>,\n ) => {\n const incomingAny = incomingMessage as any;\n const existingAny = existingMessage as any;\n const incomingIsEncrypted = incomingAny.content_type === 'mls' || Boolean(incomingAny.mls_ciphertext);\n const existingHasPlaintext =\n existingAny.content_type === 'standard' ||\n Boolean(existingAny.text) ||\n Boolean(existingAny.attachments?.length) ||\n Boolean(existingAny.sticker_url);\n const encryptedPlaintextKeys = new Set([\n 'content_type',\n 'text',\n 'attachments',\n 'sticker_url',\n 'poll_type',\n 'poll_choice_counts',\n 'latest_poll_choices',\n ]);\n const mergedMessage = { ...existingMessage };\n (Object.keys(incomingMessage) as Array<keyof typeof incomingMessage>).forEach((key) => {\n if (incomingMessage[key] === undefined) return;\n if (incomingIsEncrypted && existingHasPlaintext && encryptedPlaintextKeys.has(String(key))) return;\n (mergedMessage as any)[key] = incomingMessage[key];\n });\n if (incomingIsEncrypted && existingHasPlaintext) {\n (mergedMessage as any).content_type = 'standard';\n }\n return mergedMessage;\n };\n\n // if created_at has changed, message should be filtered and re-inserted in correct order\n // slow op but usually this only happens for a message inserted to state before actual response with correct timestamp\n if (timestampChanged) {\n messageArr = messageArr.filter((msg) => !(msg.id && message.id === msg.id));\n }\n\n // Get array length after filtering\n const messageArrayLength = messageArr.length;\n\n // for empty list just concat and return unless it's an update or deletion\n if (messageArrayLength === 0 && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageArrayLength === 0) {\n return [...messageArr];\n }\n\n if (sortBy === 'pinned_at') {\n return messageArr.concat(message);\n }\n\n const messageTime = (message[sortBy] as Date).getTime();\n const messageIsNewest = (messageArr[messageArrayLength - 1][sortBy] as Date).getTime() < messageTime;\n\n // if message is newer than last item in the list concat and return unless it's an update or deletion\n if (messageIsNewest && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageIsNewest) {\n return [...messageArr];\n }\n\n // find the closest index to push the new message\n let left = 0;\n let middle = 0;\n let right = messageArrayLength - 1;\n while (left <= right) {\n middle = Math.floor((right + left) / 2);\n if ((messageArr[middle][sortBy] as Date).getTime() <= messageTime) left = middle + 1;\n else right = middle - 1;\n }\n\n // message already exists and not filtered due to timestampChanged, update and return\n if (!timestampChanged && message.id) {\n if (messageArr[left] && message.id === messageArr[left].id) {\n messageArr[left] = mergeMessage(messageArr[left], message);\n return [...messageArr];\n }\n\n if (messageArr[left - 1] && message.id === messageArr[left - 1].id) {\n messageArr[left - 1] = mergeMessage(messageArr[left - 1], message);\n return [...messageArr];\n }\n }\n\n // Do not add updated or deleted messages to the list if they do not already exist\n // or have a timestamp change.\n if (addMessageToList) {\n messageArr.splice(left, 0, message);\n }\n\n // Remove duplicate messages by ID\n const map = new Map();\n const uniqueMessages = [];\n\n for (const msg of messageArr) {\n if (!map.has(msg.id)) {\n map.set(msg.id, true);\n uniqueMessages.push(msg);\n }\n }\n return uniqueMessages;\n}\n\nexport const enrichWithUserInfo = (items: any[], users: any[]) => {\n if (items.length === 0) return [];\n\n if (users.length === 0) {\n return items.map((item) => {\n item.user = { id: item.user?.id, name: item.user?.id, avatar: '' };\n return item;\n });\n }\n\n return items.map((item) => {\n const userId = item.user?.id;\n const lastestReactionMsg = item?.latest_reactions;\n const quotedMsg = item?.quoted_message;\n const user = users.find((u) => u.id === userId);\n if (user) {\n item.user = { id: user.id, name: user.name || user.id, avatar: user.avatar || '' };\n }\n\n if (lastestReactionMsg) {\n item.latest_reactions = lastestReactionMsg.map((reaction: any) => {\n const reactionUser = users.find((u) => u.id === reaction.user_id);\n return {\n ...reaction,\n user: {\n id: reactionUser?.id || reaction.user_id,\n name: reactionUser?.name || reaction.user_id,\n avatar: reactionUser?.avatar || '',\n },\n };\n });\n }\n\n if (quotedMsg) {\n const quotedUser = users.find((u) => u.id === quotedMsg.user?.id);\n item.quoted_message.user = {\n id: quotedUser?.id || quotedMsg.user?.id,\n name: quotedUser?.name || quotedMsg.user?.id,\n avatar: quotedUser?.avatar || '',\n };\n }\n\n return item;\n });\n};\n\nexport const getUserInfo = (id: string, users: any[]) => {\n if (users.length === 0) {\n return {\n id,\n name: id,\n avatar: '',\n };\n }\n\n const matchingUsers = users.filter((u) => u?.id === id);\n const user =\n matchingUsers.find((u) => {\n const name = typeof u?.name === 'string' ? u.name.trim() : '';\n return Boolean(name && name !== id);\n }) ||\n matchingUsers.find((u) => u?.avatar || u?.image) ||\n matchingUsers[0];\n return {\n id,\n name: user?.name || id,\n avatar: user?.avatar || '',\n };\n};\n\nexport const pickUserWithDisplayName = (id?: string, ...candidates: any[]) => {\n const userId = id || candidates.find((candidate) => typeof candidate?.id === 'string' && candidate.id)?.id;\n const users = candidates.filter((candidate) => {\n if (!candidate || typeof candidate !== 'object') return false;\n if (!userId || !candidate.id) return true;\n return candidate.id === userId;\n });\n\n const hasUsefulName = (candidate: any) => {\n const name = typeof candidate?.name === 'string' ? candidate.name.trim() : '';\n const candidateId = candidate?.id || userId;\n return Boolean(name && name !== candidateId);\n };\n\n return (\n users.find(hasUsefulName) ||\n users.find((candidate) => candidate.avatar || candidate.image) ||\n users[0] ||\n (userId ? getUserInfo(userId, []) : undefined)\n );\n};\n\nexport const getDirectChannelName = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return 'Empty channel';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.name || otherMember.user.id;\n }\n return 'Empty channel';\n};\n\nexport const getDirectChannelImage = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return '';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.avatar || '';\n }\n return '';\n};\n\nlet pendingBatchUserIds = new Set<string>();\nlet pendingBatchUserPromise: Promise<void> | null = null;\nlet resolvePendingBatchUserPromise: (() => void) | null = null;\n\n/**\n * Track user IDs we've already attempted to fetch, so we don't re-fetch\n * infinitely for users who genuinely have no name set in the backend.\n */\nconst _fetchedUserIds = new Set<string>();\n\n/**\n * Ensure all members' user info are loaded in state.users.\n * Also re-fetches users whose name equals their id (e.g. hex wallet addresses)\n * since they likely have incomplete profile data.\n * @param client ErmisChat client instance\n * @param members Array of channel members (each member must have user?.id)\n */\nexport async function ensureMembersUserInfoLoaded<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n client: ErmisChat<ErmisChatGenerics>,\n members: any[],\n) {\n // Get all memberIds\n const memberIds = (members || []).map((m: any) => m.user?.id).filter((id: string | undefined) => !!id);\n\n // Filter out ids that are missing or have incomplete info (name === id, i.e. hex address)\n const users = client.state.users;\n const missingUserIds = memberIds.filter((id: string) => {\n // Skip users we've already attempted to fetch (prevents infinite re-fetching)\n if (_fetchedUserIds.has(id)) return false;\n const existing = users[id];\n // Treat as missing if: not in state, has no name, or name is just the raw id\n return !existing || !existing.name || existing.name === existing.id;\n });\n\n // If there are users missing, fetch and update them into state\n if (missingUserIds.length > 0) {\n // Mark as attempted before fetching\n missingUserIds.forEach((id) => {\n _fetchedUserIds.add(id);\n pendingBatchUserIds.add(id);\n });\n\n if (!pendingBatchUserPromise) {\n pendingBatchUserPromise = new Promise((resolve) => {\n resolvePendingBatchUserPromise = resolve;\n });\n\n setTimeout(async () => {\n const idsToFetch = Array.from(pendingBatchUserIds);\n pendingBatchUserIds.clear();\n const resolveFn = resolvePendingBatchUserPromise;\n\n pendingBatchUserPromise = null;\n resolvePendingBatchUserPromise = null;\n\n if (idsToFetch.length > 0) {\n try {\n await client.getBatchUsers(idsToFetch);\n } catch (e) {\n client.logger('error', 'utils:ensureMembersUserInfoLoaded() - Failed to get batch users', { err: e });\n }\n }\n if (resolveFn) resolveFn();\n }, 50);\n }\n\n await pendingBatchUserPromise;\n }\n}\n\nexport const getLatestCreatedAt = (messages: any[] = []) =>\n messages.length > 0 ? Math.max(...messages.map((msg) => new Date(msg.created_at).getTime())) : 0;\n\nexport const createPacketWithHeader = (\n data: ArrayBuffer | null,\n timestamp: number | null,\n type: string,\n configMsg: any,\n): Uint8Array => {\n let HEADER_SIZE: number;\n let payload: Uint8Array;\n\n // Config messages\n if (['videoConfig', 'audioConfig', 'transciverState'].includes(type) && configMsg) {\n HEADER_SIZE = 1;\n const jsonString = JSON.stringify(configMsg);\n const encoder = new TextEncoder();\n payload = encoder.encode(jsonString);\n } else if (type === 'connected' || type === 'healthCall') {\n HEADER_SIZE = 1;\n payload = new Uint8Array(0);\n } else {\n // Data packets\n // HEADER_SIZE = 5;\n HEADER_SIZE = 9;\n payload = new Uint8Array(data!);\n }\n\n const packet = new Uint8Array(HEADER_SIZE + payload.byteLength);\n\n let typeCode: number = 0;\n switch (type) {\n case 'videoConfig':\n typeCode = 0;\n break;\n case 'audioConfig':\n typeCode = 1;\n break;\n case 'video-key':\n typeCode = 2;\n break;\n case 'video-delta':\n typeCode = 3;\n break;\n case 'audio':\n typeCode = 4;\n break;\n case 'connected':\n typeCode = 6;\n break;\n case 'transciverState':\n typeCode = 7;\n break;\n case 'healthCall':\n typeCode = 11;\n break;\n }\n\n // Byte 0: Type code\n packet[0] = typeCode;\n\n // Byte 1-8: Timestamp\n if (timestamp !== null) {\n const view = new DataView(packet.buffer);\n // view.setUint32(1, timestamp, false); // Little-endian = false (Big-endian)\n view.setBigUint64(1, BigInt(timestamp), false);\n }\n\n packet.set(payload, HEADER_SIZE);\n\n return packet;\n};\n\nexport const base64Encode = (arrayBuffer: ArrayBuffer): string => {\n let binary = '';\n const bytes = new Uint8Array(arrayBuffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n};\n\nexport const replaceCodecNumber = (input: string): string => {\n const map: Record<string, string> = {\n '2048': '123',\n '4096': '153',\n '8192': '156',\n '16384': '183',\n '32768': '186',\n };\n\n // Regex để tìm các key\n const regex = /2048|4096|8192|16384|32768/g;\n\n // Kiểm tra: Nếu input KHÔNG match bất kỳ số nào trong regex\n // thì trả về chuỗi mặc định\n if (!input.match(regex)) {\n return 'hev1.1.6.L123.B0';\n }\n\n // Nếu có match, thực hiện thay thế\n return input.replace(regex, (match) => map[match]);\n};\n\nexport const createForwardMessagePayload = <ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: FormatMessageResponse<ErmisChatGenerics>,\n targetCid: string,\n activeCid: string,\n): ForwardMessage<ErmisChatGenerics> => {\n const forwardPayload: ForwardMessage<ErmisChatGenerics> = {\n cid: targetCid,\n forward_cid: activeCid,\n forward_message_id: message.id as string,\n forward_parent_cid: (message as any).parent_cid || (message as any).cid,\n };\n\n if (\n message.sticker_url &&\n (!message.text || message.text === '') &&\n (!message.attachments || (Array.isArray(message.attachments) && message.attachments.length === 0))\n ) {\n forwardPayload.sticker_url = message.sticker_url as string;\n forwardPayload.text = message.text;\n } else {\n forwardPayload.text = message.text || '';\n if (message.attachments && message.attachments.length > 0) {\n forwardPayload.attachments = message.attachments.filter((item: any) => item.type !== 'linkPreview');\n }\n }\n\n return forwardPayload;\n};\n","import type { Logger, LoggerOption, LogLevel } from './types';\n\nexport const noopLogger: Logger = () => null;\n\ntype SdkLogBridge = (logLevel: LogLevel, ...args: unknown[]) => void;\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __ermisSdkLog: SdkLogBridge | undefined;\n}\n\nlet sdkLogger: Logger | undefined;\n\nfunction serializeLogArg(arg: unknown): string {\n if (typeof arg === 'string') return arg;\n if (arg instanceof Error) return arg.stack || arg.message;\n try {\n const serialized = JSON.stringify(arg);\n return typeof serialized === 'string' ? serialized : String(arg);\n } catch {\n return String(arg);\n }\n}\n\nfunction formatLogArgs(args: unknown[]): string {\n return args.map(serializeLogArg).join(' ');\n}\n\nfunction getExtraData(args: unknown[]): Record<string, unknown> | undefined {\n return args.length > 1 ? { args } : undefined;\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return value === 'info' || value === 'warn' || value === 'error';\n}\n\nfunction createConsoleLogger(levels: LogLevel[]): Logger | undefined {\n const enabledLevels = new Set(levels.filter(isLogLevel));\n if (enabledLevels.size === 0) return undefined;\n\n return (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => {\n const methodName = logLevel === 'error' ? 'error' : logLevel === 'warn' ? 'warn' : 'log';\n const enabled = enabledLevels.has(logLevel);\n if (!enabled || typeof globalThis === 'undefined') return;\n\n const consoleTarget = globalThis.console;\n const method = consoleTarget?.[methodName] || consoleTarget?.log;\n if (typeof method !== 'function') return;\n\n if (extraData) {\n method.call(consoleTarget, `[SDK:${logLevel}] ${message}`, extraData);\n return;\n }\n\n method.call(consoleTarget, `[SDK:${logLevel}] ${message}`);\n };\n}\n\nfunction resolveLogger(logger?: LoggerOption): Logger | undefined {\n if (typeof logger === 'function' && logger !== noopLogger) return logger;\n if (Array.isArray(logger)) return createConsoleLogger(logger);\n return undefined;\n}\n\nfunction installGlobalLogBridge(): void {\n if (typeof globalThis === 'undefined') return;\n if (!sdkLogger) {\n globalThis.__ermisSdkLog = undefined;\n return;\n }\n globalThis.__ermisSdkLog = (logLevel: LogLevel, ...args: unknown[]) => {\n sdkLog(logLevel, ...args);\n };\n}\n\nexport function getLogger(logger?: LoggerOption): Logger {\n return resolveLogger(logger) || noopLogger;\n}\n\nexport function setSdkLogger(logger?: LoggerOption): void {\n sdkLogger = resolveLogger(logger);\n installGlobalLogBridge();\n}\n\nexport function sdkLog(logLevel: LogLevel, ...args: unknown[]): void {\n if (!sdkLogger) return;\n sdkLogger(logLevel, formatLogArgs(args), getExtraData(args));\n}\n\ninstallGlobalLogBridge();\n","/**\n * Encryption Storage — Persistence layer for encryption (E2EE) state\n *\n * Defines the `EncryptionStorageAdapter` interface for platform abstraction\n * and provides `IndexedDBEncryptionStorage` as the default browser implementation.\n *\n * Stores:\n * - Device ID (per browser)\n * - Identity bytes (per user+device)\n * - E2EE messages (per channel)\n * - Group CID markers\n * - Provider key store\n * - Sync timestamps\n */\n\nimport { normalizeRequiredBytes } from './encoding';\nimport { randomId } from '../utils';\nimport type { Logger } from '../types';\nimport { setSdkLogger, sdkLog } from '../logger';\nimport MiniSearch from 'minisearch';\n\nimport type {\n ArchiveAckRecord,\n ArchiveScope,\n ChannelRepairState,\n EpochArchiveCheckpoint,\n E2eeStoredMessage,\n EventCursor,\n EncryptionStorageAdapter,\n EncryptionSyncCheckpoint,\n PendingArchiveUpload,\n PendingE2eeSendRecord,\n PendingDeferredArchive,\n PendingE2eeSnapshot,\n RemovedSyncCursor,\n RestoreProgressRecord,\n RestoreStatus,\n} from './types';\n\n// ============================================================\n// IndexedDB Implementation (Browser Default)\n// ============================================================\n\nconst DB_NAME_PREFIX = 'ermis_mls';\n/** Global DB (no userId) — only used for migrating legacy device_id */\nconst DB_NAME_LEGACY = 'ermis_mls';\nconst DB_VERSION = 6;\n\nconst STORE_IDENTITY = 'identity';\nconst STORE_MESSAGES = 'messages';\nconst STORE_PENDING_SENDS = 'pending_sends';\nconst STORE_META = 'meta';\nconst STORE_GROUPS = 'groups';\nconst STORE_ARCHIVE_UPLOADS = 'archive_uploads';\nconst STORE_DEFERRED_ARCHIVES = 'deferred_archives';\nconst STORE_ARCHIVE_ACKS = 'archive_acks';\nconst STORE_RESTORE_PROGRESS = 'restore_progress';\nconst ARCHIVE_STASH_KEY_META = 'archive_stash_key';\nconst LEGACY_SYNC_PREFIX = 'sync:';\nconst SCOPE_SYNC_PREFIX = 'scope_sync:';\nconst CHANNEL_REPAIR_PREFIX = 'channel_repair:';\nconst CHANNEL_REPAIR_LOCK_PREFIX = 'channel_repair_lock:';\nconst EPOCH_ARCHIVE_CHECKPOINT_PREFIX = 'epoch_archive_checkpoint:';\nconst ZERO_EVENT_ID = '00000000-0000-0000-0000-000000000000';\n\n/** localStorage key for device_id — global, per-browser */\nconst DEVICE_ID_LS_KEY = 'ermis_device_id';\n\nfunction normalizeDeferredArchiveRecord(record: PendingDeferredArchive): PendingDeferredArchive {\n return {\n ...record,\n encrypted_archive: {\n ciphertext: normalizeRequiredBytes(record.encrypted_archive.ciphertext, 'encrypted_archive.ciphertext'),\n nonce: normalizeRequiredBytes(record.encrypted_archive.nonce, 'encrypted_archive.nonce'),\n aead_aad: normalizeRequiredBytes(record.encrypted_archive.aead_aad, 'encrypted_archive.aead_aad'),\n },\n snapshot: {\n ...record.snapshot,\n snapshot_bytes: normalizeRequiredBytes(record.snapshot.snapshot_bytes, 'snapshot.snapshot_bytes'),\n },\n encrypted_adk: {\n ciphertext: normalizeRequiredBytes(record.encrypted_adk.ciphertext, 'encrypted_adk.ciphertext'),\n nonce: normalizeRequiredBytes(record.encrypted_adk.nonce, 'encrypted_adk.nonce'),\n },\n };\n}\n\nfunction normalizeEpochArchiveCheckpoint(record: EpochArchiveCheckpoint): EpochArchiveCheckpoint {\n return {\n ...record,\n encrypted_archive_bytes: {\n ciphertext: normalizeRequiredBytes(\n record.encrypted_archive_bytes.ciphertext,\n 'encrypted_archive_bytes.ciphertext',\n ),\n nonce: normalizeRequiredBytes(record.encrypted_archive_bytes.nonce, 'encrypted_archive_bytes.nonce'),\n },\n snapshot: {\n ...record.snapshot,\n snapshot_bytes: normalizeRequiredBytes(record.snapshot.snapshot_bytes, 'snapshot.snapshot_bytes'),\n },\n };\n}\n\nfunction eventCursorFromStoredValue(value: unknown): EventCursor | null {\n if (!value) return null;\n if (\n typeof value === 'object' &&\n typeof (value as EventCursor).created_at === 'string' &&\n typeof (value as EventCursor).event_id === 'string'\n ) {\n return value as EventCursor;\n }\n if (typeof value === 'string' && value.length > 0) {\n return { created_at: value, event_id: ZERO_EVENT_ID };\n }\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\n return { created_at: new Date(value).toISOString(), event_id: ZERO_EVENT_ID };\n }\n return null;\n}\n\n/**\n * Default encryption storage adapter using browser IndexedDB.\n *\n * Each user gets their own IndexedDB database (`ermis_mls_{userId}`) to\n * prevent cross-user state contamination during login/logout cycles.\n * `device_id` is stored in `localStorage` (global, per-browser).\n *\n * @example\n * ```ts\n * const storage = new IndexedDBEncryptionStorage('user123');\n * const deviceId = await storage.getDeviceId();\n * ```\n */\nexport class IndexedDBEncryptionStorage implements EncryptionStorageAdapter {\n private dbPromise: Promise<IDBDatabase> | null = null;\n private readonly dbName: string;\n\n /**\n * @param userId - The current user's ID. Used to scope the IndexedDB\n * database name so each user's encryption state is isolated.\n * Pass empty string for legacy/global access (migration only).\n */\n constructor(userId: string = '', logger?: Logger) {\n if (logger) setSdkLogger(logger);\n if (userId) {\n this.dbName = `${DB_NAME_PREFIX}_${userId}`;\n } else {\n // Legacy fallback — global DB (used during device_id migration)\n this.dbName = DB_NAME_LEGACY;\n }\n }\n\n /**\n * Open (or create) the IndexedDB database.\n * Caches the connection promise for reuse.\n */\n private openDB(): Promise<IDBDatabase> {\n if (this.dbPromise) return this.dbPromise;\n\n this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, DB_VERSION);\n\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n const db = (event.target as IDBOpenDBRequest).result;\n\n // Identity store: key = \"userId:deviceId\"\n if (!db.objectStoreNames.contains(STORE_IDENTITY)) {\n db.createObjectStore(STORE_IDENTITY);\n }\n\n // Messages store: key = message id, indexes by cid\n if (!db.objectStoreNames.contains(STORE_MESSAGES)) {\n const msgStore = db.createObjectStore(STORE_MESSAGES, {\n keyPath: 'id',\n });\n msgStore.createIndex('cid', 'cid', { unique: false });\n msgStore.createIndex('cid_created', ['cid', 'created_at'], { unique: false });\n }\n\n if (!db.objectStoreNames.contains(STORE_PENDING_SENDS)) {\n const pendingStore = db.createObjectStore(STORE_PENDING_SENDS, {\n keyPath: 'message_id',\n });\n pendingStore.createIndex('status', 'status', { unique: false });\n pendingStore.createIndex('cid', 'cid', { unique: false });\n pendingStore.createIndex('updated_at', 'updated_at', { unique: false });\n }\n\n // Meta store: key-value for device_id, snapshot, sync timestamps\n if (!db.objectStoreNames.contains(STORE_META)) {\n db.createObjectStore(STORE_META);\n }\n\n // Groups store: key = cid → marker\n if (!db.objectStoreNames.contains(STORE_GROUPS)) {\n db.createObjectStore(STORE_GROUPS);\n }\n\n if (!db.objectStoreNames.contains(STORE_ARCHIVE_UPLOADS)) {\n db.createObjectStore(STORE_ARCHIVE_UPLOADS);\n }\n\n if (!db.objectStoreNames.contains(STORE_DEFERRED_ARCHIVES)) {\n db.createObjectStore(STORE_DEFERRED_ARCHIVES);\n }\n\n if (!db.objectStoreNames.contains(STORE_ARCHIVE_ACKS)) {\n db.createObjectStore(STORE_ARCHIVE_ACKS);\n }\n\n if (!db.objectStoreNames.contains(STORE_RESTORE_PROGRESS)) {\n const restoreStore = db.createObjectStore(STORE_RESTORE_PROGRESS, {\n keyPath: ['device_id', 'cid'],\n });\n restoreStore.createIndex('status', 'status', { unique: false });\n restoreStore.createIndex('device_id', 'device_id', { unique: false });\n restoreStore.createIndex('device_status', ['device_id', 'status'], { unique: false });\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n this.dbPromise = null;\n reject(request.error);\n };\n });\n\n return this.dbPromise;\n }\n\n // ---- Device ID (global, per-browser via localStorage) ----\n\n async getDeviceId(): Promise<string> {\n // 1. Check localStorage first\n if (typeof localStorage !== 'undefined') {\n const stored = localStorage.getItem(DEVICE_ID_LS_KEY);\n if (stored) return stored;\n }\n\n // 2. Backward compat: migrate from legacy global IndexedDB\n try {\n const legacyId = await this._migrateLegacyDeviceId();\n if (legacyId) return legacyId;\n } catch (_) {\n // IndexedDB unavailable — generate new\n }\n\n // 3. Generate new device ID\n const deviceId = `web-${randomId()}`;\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(DEVICE_ID_LS_KEY, deviceId);\n }\n return deviceId;\n }\n\n /**\n * Migrate device_id from legacy global IndexedDB (`ermis_mls`) to localStorage.\n * Returns the migrated ID or null if not found.\n */\n private async _migrateLegacyDeviceId(): Promise<string | null> {\n return new Promise<string | null>((resolve) => {\n const request = indexedDB.open(DB_NAME_LEGACY, DB_VERSION);\n\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n // Legacy DB doesn't exist yet — nothing to migrate\n const db = (event.target as IDBOpenDBRequest).result;\n // Create stores to avoid errors, but we won't find device_id\n if (!db.objectStoreNames.contains(STORE_META)) {\n db.createObjectStore(STORE_META);\n }\n if (!db.objectStoreNames.contains(STORE_IDENTITY)) {\n db.createObjectStore(STORE_IDENTITY);\n }\n if (!db.objectStoreNames.contains(STORE_MESSAGES)) {\n const msgStore = db.createObjectStore(STORE_MESSAGES, { keyPath: 'id' });\n msgStore.createIndex('cid', 'cid', { unique: false });\n msgStore.createIndex('cid_created', ['cid', 'created_at'], { unique: false });\n }\n if (!db.objectStoreNames.contains(STORE_PENDING_SENDS)) {\n const pendingStore = db.createObjectStore(STORE_PENDING_SENDS, { keyPath: 'message_id' });\n pendingStore.createIndex('status', 'status', { unique: false });\n pendingStore.createIndex('cid', 'cid', { unique: false });\n pendingStore.createIndex('updated_at', 'updated_at', { unique: false });\n }\n if (!db.objectStoreNames.contains(STORE_GROUPS)) {\n db.createObjectStore(STORE_GROUPS);\n }\n if (!db.objectStoreNames.contains(STORE_ARCHIVE_UPLOADS)) {\n db.createObjectStore(STORE_ARCHIVE_UPLOADS);\n }\n\n if (!db.objectStoreNames.contains(STORE_DEFERRED_ARCHIVES)) {\n db.createObjectStore(STORE_DEFERRED_ARCHIVES);\n }\n\n if (!db.objectStoreNames.contains(STORE_ARCHIVE_ACKS)) {\n db.createObjectStore(STORE_ARCHIVE_ACKS);\n }\n\n if (!db.objectStoreNames.contains(STORE_RESTORE_PROGRESS)) {\n const restoreStore = db.createObjectStore(STORE_RESTORE_PROGRESS, {\n keyPath: ['device_id', 'cid'],\n });\n restoreStore.createIndex('status', 'status', { unique: false });\n restoreStore.createIndex('device_id', 'device_id', { unique: false });\n restoreStore.createIndex('device_status', ['device_id', 'status'], { unique: false });\n }\n };\n\n request.onsuccess = () => {\n const db = request.result;\n try {\n if (!db.objectStoreNames.contains(STORE_META)) {\n db.close();\n resolve(null);\n return;\n }\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const getReq = store.get('device_id');\n getReq.onsuccess = () => {\n const legacyId = getReq.result as string | undefined;\n db.close();\n if (legacyId && typeof localStorage !== 'undefined') {\n localStorage.setItem(DEVICE_ID_LS_KEY, legacyId);\n sdkLog('info', '[Encryption Storage] Migrated device_id from IndexedDB to localStorage:', legacyId);\n resolve(legacyId);\n } else {\n resolve(null);\n }\n };\n getReq.onerror = () => {\n db.close();\n resolve(null);\n };\n } catch (_) {\n db.close();\n resolve(null);\n }\n };\n\n request.onerror = () => resolve(null);\n });\n }\n\n // ---- Identity ----\n\n async saveIdentity(userId: string, deviceId: string, identityBytes: Uint8Array): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_IDENTITY, 'readwrite');\n const store = tx.objectStore(STORE_IDENTITY);\n store.put(identityBytes, `${userId}:${deviceId}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadIdentity(userId: string, deviceId: string): Promise<Uint8Array | null> {\n const db = await this.openDB();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction(STORE_IDENTITY, 'readonly');\n const store = tx.objectStore(STORE_IDENTITY);\n const request = store.get(`${userId}:${deviceId}`);\n request.onsuccess = () => resolve((request.result as Uint8Array) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n // ---- E2EE Messages ----\n\n async saveE2eeMessage(message: E2eeStoredMessage): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readwrite');\n const store = tx.objectStore(STORE_MESSAGES);\n store.put(message);\n tx.oncomplete = () => {\n // Incrementally update MiniSearch index\n this._indexMessage(message);\n resolve();\n };\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadE2eeMessage(messageId: string): Promise<E2eeStoredMessage | null> {\n const db = await this.openDB();\n return new Promise<E2eeStoredMessage | null>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readonly');\n const store = tx.objectStore(STORE_MESSAGES);\n const request = store.get(messageId);\n request.onsuccess = () => resolve((request.result as E2eeStoredMessage) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async loadE2eeMessages(messageIds: string[]): Promise<Map<string, E2eeStoredMessage>> {\n const ids = Array.from(new Set(messageIds.filter(Boolean)));\n if (ids.length === 0) return new Map();\n\n const db = await this.openDB();\n return new Promise<Map<string, E2eeStoredMessage>>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readonly');\n const store = tx.objectStore(STORE_MESSAGES);\n const results = new Map<string, E2eeStoredMessage>();\n\n for (const id of ids) {\n const request = store.get(id);\n request.onsuccess = () => {\n if (request.result) {\n results.set(id, request.result as E2eeStoredMessage);\n }\n };\n request.onerror = () => reject(request.error);\n }\n\n tx.oncomplete = () => resolve(results);\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async deleteE2eeMessage(messageId: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readwrite');\n const store = tx.objectStore(STORE_MESSAGES);\n store.delete(messageId);\n tx.oncomplete = () => {\n if (this._searchIndex && this._indexReady) {\n try {\n this._searchIndex.discard(messageId);\n } catch (_) {\n // Ignore missing records in index\n }\n this._indexedIds.delete(messageId);\n }\n resolve();\n };\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async getE2eeMessages(cid: string, limit = 50): Promise<E2eeStoredMessage[]> {\n const db = await this.openDB();\n return new Promise<E2eeStoredMessage[]>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readonly');\n const store = tx.objectStore(STORE_MESSAGES);\n const index = store.index('cid');\n const request = index.getAll(cid);\n request.onsuccess = () => {\n const msgs = (request.result as E2eeStoredMessage[]) || [];\n // Sort by created_at descending, take limit\n msgs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());\n resolve(msgs.slice(0, limit));\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async clearE2eeMessages(cid: string): Promise<void> {\n const db = await this.openDB();\n\n // Collect message IDs for this channel to purge from search index\n const msgIds: string[] = [];\n\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readwrite');\n const store = tx.objectStore(STORE_MESSAGES);\n const index = store.index('cid');\n const request = index.openCursor(cid);\n request.onsuccess = (event: Event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue | null>).result;\n if (cursor) {\n msgIds.push((cursor.value as E2eeStoredMessage).id);\n cursor.delete();\n cursor.continue();\n }\n };\n tx.oncomplete = () => {\n // Purge cleared messages from MiniSearch index\n if (this._searchIndex && this._indexReady) {\n for (const id of msgIds) {\n try {\n this._searchIndex.discard(id);\n this._indexedIds.delete(id);\n } catch (_) {\n /* already removed */\n }\n }\n }\n resolve();\n };\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- Pending E2EE Sends ----\n\n async savePendingE2eeSend(record: PendingE2eeSendRecord): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_PENDING_SENDS, 'readwrite');\n tx.objectStore(STORE_PENDING_SENDS).put(record);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadPendingE2eeSend(messageId: string): Promise<PendingE2eeSendRecord | null> {\n const db = await this.openDB();\n return new Promise<PendingE2eeSendRecord | null>((resolve, reject) => {\n const tx = db.transaction(STORE_PENDING_SENDS, 'readonly');\n const request = tx.objectStore(STORE_PENDING_SENDS).get(messageId);\n request.onsuccess = () => resolve((request.result as PendingE2eeSendRecord) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async listPendingE2eeSends(statuses?: string[]): Promise<PendingE2eeSendRecord[]> {\n const db = await this.openDB();\n return new Promise<PendingE2eeSendRecord[]>((resolve, reject) => {\n const tx = db.transaction(STORE_PENDING_SENDS, 'readonly');\n const store = tx.objectStore(STORE_PENDING_SENDS);\n const results: PendingE2eeSendRecord[] = [];\n const allowed = statuses && statuses.length > 0 ? new Set(statuses) : null;\n const request = store.openCursor();\n request.onsuccess = (event: Event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue | null>).result;\n if (cursor) {\n const value = cursor.value as PendingE2eeSendRecord;\n if (!allowed || allowed.has(value.status)) results.push(value);\n cursor.continue();\n }\n };\n tx.oncomplete = () => {\n results.sort((a, b) => a.updated_at - b.updated_at);\n resolve(results);\n };\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async deletePendingE2eeSend(messageId: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_PENDING_SENDS, 'readwrite');\n tx.objectStore(STORE_PENDING_SENDS).delete(messageId);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- E2EE Message Search (MiniSearch-powered) ----\n\n /** MiniSearch instance — lazily initialized on first search. */\n private _searchIndex: MiniSearch<E2eeStoredMessage> | null = null;\n /** Set of indexed message IDs — for dedup on incremental add. */\n private _indexedIds: Set<string> = new Set();\n /** Whether the full index has been built from IndexedDB. */\n private _indexReady = false;\n /** Promise for the build-in-progress (prevents double-build). */\n private _indexBuildPromise: Promise<void> | null = null;\n\n /**\n * Create a fresh MiniSearch instance with fields tuned for chat messages.\n */\n private _createSearchIndex(): MiniSearch<E2eeStoredMessage> {\n return new MiniSearch<E2eeStoredMessage>({\n fields: ['text'],\n storeFields: [\n 'id',\n 'cid',\n 'text',\n 'user_id',\n 'user',\n 'created_at',\n 'type',\n 'content_type',\n 'parent_id',\n 'quoted_message_id',\n 'mentioned_users',\n 'mentioned_all',\n 'attachments',\n 'sticker_url',\n 'pinned',\n 'reaction_counts',\n 'latest_reactions',\n 'poll_type',\n 'poll_choice_counts',\n 'latest_poll_choices',\n 'quoted_message',\n ],\n idField: 'id',\n // Vietnamese-friendly: lowercase, strip diacritics for indexing\n processTerm: (term) => {\n if (!term) return null;\n return term\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/đ/g, 'd');\n },\n searchOptions: {\n // Also strip diacritics on search queries for consistent matching\n processTerm: (term) => {\n if (!term) return null;\n return term\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/đ/g, 'd');\n },\n prefix: true,\n fuzzy: 0.2,\n combineWith: 'AND',\n },\n });\n }\n\n /**\n * Build the search index from all messages in IndexedDB.\n * Called lazily on first search. Subsequent calls are no-ops.\n */\n private async _ensureIndex(): Promise<void> {\n if (this._indexReady) return;\n if (this._indexBuildPromise) return this._indexBuildPromise;\n\n this._indexBuildPromise = (async () => {\n const db = await this.openDB();\n const allMsgs = await new Promise<E2eeStoredMessage[]>((resolve, reject) => {\n const tx = db.transaction(STORE_MESSAGES, 'readonly');\n const store = tx.objectStore(STORE_MESSAGES);\n const request = store.getAll();\n request.onsuccess = () => resolve((request.result as E2eeStoredMessage[]) || []);\n request.onerror = () => reject(request.error);\n });\n\n this._searchIndex = this._createSearchIndex();\n this._indexedIds = new Set();\n\n // Filter messages with searchable text content\n const indexable = allMsgs.filter((msg) => msg.text && msg.text.length > 0);\n if (indexable.length > 0) {\n this._searchIndex.addAll(indexable);\n for (const msg of indexable) {\n this._indexedIds.add(msg.id);\n }\n }\n\n this._indexReady = true;\n this._indexBuildPromise = null;\n sdkLog('info', `[Encryption Storage] Search index built: ${indexable.length} messages indexed`);\n })();\n\n return this._indexBuildPromise;\n }\n\n /**\n * Incrementally add/update a single message in the search index.\n * Called from saveE2eeMessage() after successful IndexedDB write.\n */\n private _indexMessage(message: E2eeStoredMessage): void {\n if (!this._searchIndex || !this._indexReady) return;\n if (!message.text || message.text.length === 0) return;\n\n try {\n if (this._indexedIds.has(message.id)) {\n // Update: remove old, add new\n this._searchIndex.discard(message.id);\n }\n this._searchIndex.add(message);\n this._indexedIds.add(message.id);\n } catch (err) {\n sdkLog('warn', '[Encryption Storage] Failed to index message:', message.id, err);\n }\n }\n\n async searchE2eeMessages(searchTerm: string, limit = 25): Promise<E2eeStoredMessage[]> {\n await this._ensureIndex();\n if (!this._searchIndex) return [];\n\n const results = this._searchIndex.search(searchTerm);\n\n // Sort by created_at descending (MiniSearch returns by relevance score)\n const sorted = results\n .sort((a, b) => new Date((b as any).created_at).getTime() - new Date((a as any).created_at).getTime())\n .slice(0, limit);\n\n return sorted as unknown as E2eeStoredMessage[];\n }\n\n async searchE2eeMessagesByCid(cid: string, searchTerm: string, limit = 25): Promise<E2eeStoredMessage[]> {\n await this._ensureIndex();\n if (!this._searchIndex) return [];\n\n const results = this._searchIndex.search(searchTerm, {\n filter: (result) => (result as any).cid === cid,\n });\n\n const sorted = results\n .sort((a, b) => new Date((b as any).created_at).getTime() - new Date((a as any).created_at).getTime())\n .slice(0, limit);\n\n return sorted as unknown as E2eeStoredMessage[];\n }\n\n // ---- Group State ----\n\n async saveGroupState(cid: string, marker: unknown): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_GROUPS, 'readwrite');\n const store = tx.objectStore(STORE_GROUPS);\n store.put(marker, cid);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadGroupState(cid: string): Promise<unknown | null> {\n const db = await this.openDB();\n return new Promise<unknown | null>((resolve, reject) => {\n const tx = db.transaction(STORE_GROUPS, 'readonly');\n const store = tx.objectStore(STORE_GROUPS);\n const request = store.get(cid);\n request.onsuccess = () => resolve(request.result || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async listGroupCids(): Promise<string[]> {\n const db = await this.openDB();\n return new Promise<string[]>((resolve, reject) => {\n const tx = db.transaction(STORE_GROUPS, 'readonly');\n const store = tx.objectStore(STORE_GROUPS);\n const request = store.getAllKeys();\n request.onsuccess = () => resolve((request.result as string[]) || []);\n request.onerror = () => reject(request.error);\n });\n }\n\n async deleteGroup(cid: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_GROUPS, 'readwrite');\n const store = tx.objectStore(STORE_GROUPS);\n store.delete(cid);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- Provider State ----\n\n async saveProviderState(userId: string, deviceId: string, providerBytes: Uint8Array): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(providerBytes, `provider:${userId}:${deviceId}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadProviderState(userId: string, deviceId: string): Promise<Uint8Array | null> {\n const db = await this.openDB();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(`provider:${userId}:${deviceId}`);\n request.onsuccess = () => resolve((request.result as Uint8Array) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n // ---- Sync Timestamps ----\n\n async saveSyncTimestamp(cid: string, timestamp: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(timestamp, `${LEGACY_SYNC_PREFIX}${cid}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadSyncTimestamp(cid: string): Promise<string | null> {\n const db = await this.openDB();\n return new Promise<string | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(`${LEGACY_SYNC_PREFIX}${cid}`);\n request.onsuccess = () => resolve((request.result as string) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n // ---- Batch Sync Cursors ----\n\n async loadAllSyncTimestamps(): Promise<Record<string, string>> {\n const db = await this.openDB();\n return new Promise<Record<string, string>>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const cursors: Record<string, string> = {};\n const cursorReq = store.openCursor();\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (cursor) {\n const key = cursor.key as string;\n if (key.startsWith(LEGACY_SYNC_PREFIX) && key !== 'sync:removed_channels') {\n const cid = key.slice(LEGACY_SYNC_PREFIX.length);\n cursors[cid] = cursor.value as string;\n }\n cursor.continue();\n } else {\n resolve(cursors);\n }\n };\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n }\n\n async loadScopeSyncCursor(scopeCid: string): Promise<EventCursor | null> {\n const db = await this.openDB();\n return new Promise<EventCursor | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const scopeReq = store.get(`${SCOPE_SYNC_PREFIX}${scopeCid}`);\n scopeReq.onsuccess = () => {\n const scopeCursor = eventCursorFromStoredValue(scopeReq.result);\n if (scopeCursor) {\n resolve(scopeCursor);\n return;\n }\n\n const legacyReq = store.get(`${LEGACY_SYNC_PREFIX}${scopeCid}`);\n legacyReq.onsuccess = () => resolve(eventCursorFromStoredValue(legacyReq.result));\n legacyReq.onerror = () => reject(legacyReq.error);\n };\n scopeReq.onerror = () => reject(scopeReq.error);\n });\n }\n\n async saveScopeSyncCursor(scopeCid: string, cursor: EventCursor): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(cursor, `${SCOPE_SYNC_PREFIX}${scopeCid}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadAllScopeSyncCursors(): Promise<Record<string, EventCursor>> {\n const db = await this.openDB();\n return new Promise<Record<string, EventCursor>>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const legacyCursors: Record<string, EventCursor> = {};\n const scopeCursors: Record<string, EventCursor> = {};\n const cursorReq = store.openCursor();\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (cursor) {\n const key = cursor.key as string;\n if (key.startsWith(SCOPE_SYNC_PREFIX)) {\n const scopeCid = key.slice(SCOPE_SYNC_PREFIX.length);\n const value = eventCursorFromStoredValue(cursor.value);\n if (value) scopeCursors[scopeCid] = value;\n } else if (key.startsWith(LEGACY_SYNC_PREFIX) && key !== 'sync:removed_channels') {\n const scopeCid = key.slice(LEGACY_SYNC_PREFIX.length);\n const value = eventCursorFromStoredValue(cursor.value);\n if (value) legacyCursors[scopeCid] = value;\n }\n cursor.continue();\n } else {\n resolve({ ...legacyCursors, ...scopeCursors });\n }\n };\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n }\n\n async saveAllScopeSyncCursors(cursors: Record<string, EventCursor>): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n for (const [scopeCid, cursor] of Object.entries(cursors)) {\n store.put(cursor, `${SCOPE_SYNC_PREFIX}${scopeCid}`);\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadChannelRepairState(scopeCid: string): Promise<ChannelRepairState | null> {\n const db = await this.openDB();\n return new Promise<ChannelRepairState | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(`${CHANNEL_REPAIR_PREFIX}${scopeCid}`);\n request.onsuccess = () => resolve((request.result as ChannelRepairState) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async saveChannelRepairState(state: ChannelRepairState): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(state, `${CHANNEL_REPAIR_PREFIX}${state.scope_cid}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async deleteChannelRepairState(scopeCid: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.delete(`${CHANNEL_REPAIR_PREFIX}${scopeCid}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async saveEncryptionSyncCheckpoint(checkpoint: EncryptionSyncCheckpoint): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n\n store.put(checkpoint.provider_bytes, `provider:${checkpoint.user_id}:${checkpoint.device_id}`);\n\n for (const [scopeCid, cursor] of Object.entries(checkpoint.scope_cursors || {})) {\n store.put(cursor, `${SCOPE_SYNC_PREFIX}${scopeCid}`);\n }\n\n for (const [cid, snapshots] of Object.entries(checkpoint.pending_snapshots || {})) {\n const key = `pending_e2ee_snapshots:${cid}`;\n if (snapshots.length === 0) {\n store.delete(key);\n } else {\n store.put(snapshots, key);\n }\n }\n\n for (const state of checkpoint.repair_states || []) {\n store.put(state, `${CHANNEL_REPAIR_PREFIX}${state.scope_cid}`);\n }\n\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async tryAcquireRepairLock(scopeCid: string, ownerId: string, ttlMs: number): Promise<boolean> {\n const db = await this.openDB();\n return new Promise<boolean>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n const key = `${CHANNEL_REPAIR_LOCK_PREFIX}${scopeCid}`;\n const request = store.get(key);\n let acquired = false;\n\n request.onsuccess = () => {\n const now = Date.now();\n const current = request.result as { owner_id?: string; expires_at?: number } | undefined;\n if (current?.owner_id && current.expires_at && current.expires_at > now && current.owner_id !== ownerId) {\n acquired = false;\n return;\n }\n acquired = true;\n store.put({ scope_cid: scopeCid, owner_id: ownerId, expires_at: now + ttlMs, updated_at: now }, key);\n };\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve(acquired);\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async releaseRepairLock(scopeCid: string, ownerId: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n const key = `${CHANNEL_REPAIR_LOCK_PREFIX}${scopeCid}`;\n const request = store.get(key);\n\n request.onsuccess = () => {\n const current = request.result as { owner_id?: string } | undefined;\n if (!current || current.owner_id === ownerId) {\n store.delete(key);\n }\n };\n request.onerror = () => reject(request.error);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async saveAllSyncTimestamps(timestamps: Record<string, string>): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n for (const [cid, ts] of Object.entries(timestamps)) {\n store.put(ts, `${LEGACY_SYNC_PREFIX}${cid}`);\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadRemovedSyncCursor(): Promise<RemovedSyncCursor | null> {\n const db = await this.openDB();\n return new Promise<RemovedSyncCursor | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get('sync:removed_channels');\n request.onsuccess = () => {\n const value = request.result;\n if (!value) {\n resolve(null);\n return;\n }\n if (typeof value === 'object' && typeof value.removed_at === 'string' && typeof value.event_id === 'string') {\n resolve(value as RemovedSyncCursor);\n return;\n }\n // Legacy storage may hold a numeric millisecond cursor, or the first\n // composite cursor shape may hold removed_at as a number.\n const legacyMs = typeof value === 'object' ? Number(value.removed_at) : Number(value);\n if (Number.isFinite(legacyMs) && legacyMs > 0) {\n resolve({\n removed_at: new Date(legacyMs).toISOString(),\n event_id:\n typeof value === 'object' && typeof value.event_id === 'string'\n ? value.event_id\n : '00000000-0000-0000-0000-000000000000',\n });\n return;\n }\n resolve(null);\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async saveRemovedSyncCursor(cursor: RemovedSyncCursor): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(cursor, 'sync:removed_channels');\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- Pending E2EE encrypted snapshots ----\n\n async loadPendingE2eeSnapshots(cid: string): Promise<PendingE2eeSnapshot[]> {\n const db = await this.openDB();\n return new Promise<PendingE2eeSnapshot[]>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(`pending_e2ee_snapshots:${cid}`);\n request.onsuccess = () => resolve((request.result as PendingE2eeSnapshot[]) || []);\n request.onerror = () => reject(request.error);\n });\n }\n\n async savePendingE2eeSnapshots(cid: string, messages: PendingE2eeSnapshot[]): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n const key = `pending_e2ee_snapshots:${cid}`;\n if (messages.length === 0) {\n store.delete(key);\n } else {\n store.put(messages, key);\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- Pending Evictions ----\n\n async loadPendingEvictions(): Promise<Record<string, string[]>> {\n const db = await this.openDB();\n return new Promise<Record<string, string[]>>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get('pending_evictions');\n request.onsuccess = () => resolve((request.result as Record<string, string[]>) || {});\n request.onerror = () => reject(request.error);\n });\n }\n\n async savePendingEvictions(data: Record<string, string[]>): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n if (Object.keys(data).length === 0) {\n store.delete('pending_evictions');\n } else {\n store.put(data, 'pending_evictions');\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n // ---- PIN Epoch Archive recovery ----\n\n async saveArchiveUpload(upload: PendingArchiveUpload): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_ARCHIVE_UPLOADS, 'readwrite');\n const store = tx.objectStore(STORE_ARCHIVE_UPLOADS);\n const archiveBlobId = (upload.upload as any)?.archive_blob_id || 'unknown';\n store.put(upload, `${upload.cid}:${upload.epoch}:${archiveBlobId}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadPendingArchiveUploads(): Promise<PendingArchiveUpload[]> {\n const db = await this.openDB();\n return new Promise<PendingArchiveUpload[]>((resolve, reject) => {\n const tx = db.transaction(STORE_ARCHIVE_UPLOADS, 'readonly');\n const store = tx.objectStore(STORE_ARCHIVE_UPLOADS);\n const request = store.getAll();\n request.onsuccess = () => resolve((request.result as PendingArchiveUpload[]) || []);\n request.onerror = () => reject(request.error);\n });\n }\n\n async deleteArchiveUpload(cid: string, epoch: number, archiveBlobId?: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_ARCHIVE_UPLOADS, 'readwrite');\n const store = tx.objectStore(STORE_ARCHIVE_UPLOADS);\n if (archiveBlobId) {\n store.delete(`${cid}:${epoch}:${archiveBlobId}`);\n } else {\n const prefix = `${cid}:${epoch}:`;\n const cursorReq = store.openCursor();\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (cursor) {\n if (String(cursor.key).startsWith(prefix)) cursor.delete();\n cursor.continue();\n }\n };\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async saveDeferredArchive(archive: PendingDeferredArchive): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_DEFERRED_ARCHIVES, 'readwrite');\n const store = tx.objectStore(STORE_DEFERRED_ARCHIVES);\n store.put(archive, `${archive.cid}:${archive.epoch}:${archive.archive_blob_id}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadPendingDeferredArchives(): Promise<PendingDeferredArchive[]> {\n const db = await this.openDB();\n return new Promise<PendingDeferredArchive[]>((resolve, reject) => {\n const tx = db.transaction(STORE_DEFERRED_ARCHIVES, 'readonly');\n const store = tx.objectStore(STORE_DEFERRED_ARCHIVES);\n const request = store.getAll();\n request.onsuccess = () =>\n resolve(((request.result as PendingDeferredArchive[]) || []).map(normalizeDeferredArchiveRecord));\n request.onerror = () => reject(request.error);\n });\n }\n\n async deleteDeferredArchive(cid: string, epoch: number, archiveBlobId?: string): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_DEFERRED_ARCHIVES, 'readwrite');\n const store = tx.objectStore(STORE_DEFERRED_ARCHIVES);\n if (archiveBlobId) {\n store.delete(`${cid}:${epoch}:${archiveBlobId}`);\n } else {\n const prefix = `${cid}:${epoch}:`;\n const cursorReq = store.openCursor();\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (cursor) {\n if (String(cursor.key).startsWith(prefix)) cursor.delete();\n cursor.continue();\n }\n };\n }\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async saveArchiveAck(record: ArchiveAckRecord): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_ARCHIVE_ACKS, 'readwrite');\n const store = tx.objectStore(STORE_ARCHIVE_ACKS);\n store.put(record, `${record.cid}:${record.epoch}:${record.scope}:${record.coverage_key}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadArchiveAck(\n cid: string,\n epoch: number,\n scope: ArchiveScope,\n coverageKey: string,\n ): Promise<ArchiveAckRecord | null> {\n const db = await this.openDB();\n return new Promise<ArchiveAckRecord | null>((resolve, reject) => {\n const tx = db.transaction(STORE_ARCHIVE_ACKS, 'readonly');\n const store = tx.objectStore(STORE_ARCHIVE_ACKS);\n const request = store.get(`${cid}:${epoch}:${scope}:${coverageKey}`);\n request.onsuccess = () => {\n if (request.result || scope !== 'account_owned') {\n resolve((request.result as ArchiveAckRecord) || null);\n return;\n }\n const legacyRequest = store.get(`${cid}:${epoch}:${coverageKey}`);\n legacyRequest.onsuccess = () => {\n const legacy = legacyRequest.result as ArchiveAckRecord | undefined;\n resolve(\n legacy\n ? {\n ...legacy,\n scope: 'account_owned',\n coverage_key: coverageKey,\n recovery_key_id: legacy.recovery_key_id || coverageKey,\n }\n : null,\n );\n };\n legacyRequest.onerror = () => reject(legacyRequest.error);\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async saveEpochArchiveCheckpoint(checkpoint: EpochArchiveCheckpoint): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n tx.objectStore(STORE_META).put(\n checkpoint,\n `${EPOCH_ARCHIVE_CHECKPOINT_PREFIX}${checkpoint.scope_cid}:${checkpoint.epoch}`,\n );\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadEpochArchiveCheckpoint(scopeCid: string, epoch: number): Promise<EpochArchiveCheckpoint | null> {\n const db = await this.openDB();\n return new Promise<EpochArchiveCheckpoint | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const request = tx.objectStore(STORE_META).get(`${EPOCH_ARCHIVE_CHECKPOINT_PREFIX}${scopeCid}:${epoch}`);\n request.onsuccess = () =>\n resolve(request.result ? normalizeEpochArchiveCheckpoint(request.result as EpochArchiveCheckpoint) : null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async loadEpochArchiveCheckpoints(): Promise<EpochArchiveCheckpoint[]> {\n const db = await this.openDB();\n return new Promise<EpochArchiveCheckpoint[]>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const checkpoints: EpochArchiveCheckpoint[] = [];\n const request = store.openCursor();\n request.onsuccess = () => {\n const cursor = request.result;\n if (!cursor) {\n resolve(checkpoints);\n return;\n }\n if (String(cursor.key).startsWith(EPOCH_ARCHIVE_CHECKPOINT_PREFIX)) {\n checkpoints.push(normalizeEpochArchiveCheckpoint(cursor.value as EpochArchiveCheckpoint));\n }\n cursor.continue();\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async deleteEpochArchiveCheckpoint(scopeCid: string, epoch: number): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n tx.objectStore(STORE_META).delete(`${EPOCH_ARCHIVE_CHECKPOINT_PREFIX}${scopeCid}:${epoch}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async saveArchiveStashKey(key: CryptoKey): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(key, ARCHIVE_STASH_KEY_META);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadArchiveStashKey(): Promise<CryptoKey | null> {\n const db = await this.openDB();\n return new Promise<CryptoKey | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(ARCHIVE_STASH_KEY_META);\n request.onsuccess = () => resolve((request.result as CryptoKey) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async saveRecoveryPublicKey(userId: string, publicKey: Uint8Array): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readwrite');\n const store = tx.objectStore(STORE_META);\n store.put(publicKey, `recovery_public_key:${userId}`);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadRecoveryPublicKey(userId: string): Promise<Uint8Array | null> {\n const db = await this.openDB();\n return new Promise<Uint8Array | null>((resolve, reject) => {\n const tx = db.transaction(STORE_META, 'readonly');\n const store = tx.objectStore(STORE_META);\n const request = store.get(`recovery_public_key:${userId}`);\n request.onsuccess = () => resolve((request.result as Uint8Array) || null);\n request.onerror = () => reject(request.error);\n });\n }\n\n async saveRestoreProgress(record: RestoreProgressRecord): Promise<void> {\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_RESTORE_PROGRESS, 'readwrite');\n const store = tx.objectStore(STORE_RESTORE_PROGRESS);\n store.put(record);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n async loadRestoreProgress(userId: string, deviceId: string, cid: string): Promise<RestoreProgressRecord | null> {\n const db = await this.openDB();\n return new Promise<RestoreProgressRecord | null>((resolve, reject) => {\n const tx = db.transaction(STORE_RESTORE_PROGRESS, 'readonly');\n const store = tx.objectStore(STORE_RESTORE_PROGRESS);\n const request = store.get([deviceId, cid]);\n request.onsuccess = () => {\n const record = request.result as RestoreProgressRecord | undefined;\n resolve(record && record.user_id === userId ? record : null);\n };\n request.onerror = () => reject(request.error);\n });\n }\n\n async loadIncompleteRestores(userId: string, deviceId: string): Promise<RestoreProgressRecord[]> {\n const statuses: RestoreStatus[] = ['pending', 'running', 'partial', 'failed'];\n const groups = await Promise.all(\n statuses.map((status) => this._loadRestoreProgressByDeviceStatus(userId, deviceId, status)),\n );\n return groups.flat();\n }\n\n async loadRestoresWithPermanentGaps(userId: string, deviceId: string): Promise<RestoreProgressRecord[]> {\n return this._loadRestoreProgressByDeviceStatus(userId, deviceId, 'done_with_gaps');\n }\n\n async deleteRestoreProgress(userId: string, deviceId: string, cid: string): Promise<void> {\n const existing = await this.loadRestoreProgress(userId, deviceId, cid);\n if (!existing) return;\n const db = await this.openDB();\n return new Promise<void>((resolve, reject) => {\n const tx = db.transaction(STORE_RESTORE_PROGRESS, 'readwrite');\n const store = tx.objectStore(STORE_RESTORE_PROGRESS);\n store.delete([deviceId, cid]);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n }\n\n private async _loadRestoreProgressByDeviceStatus(\n userId: string,\n deviceId: string,\n status: RestoreStatus,\n ): Promise<RestoreProgressRecord[]> {\n const db = await this.openDB();\n return new Promise<RestoreProgressRecord[]>((resolve, reject) => {\n const tx = db.transaction(STORE_RESTORE_PROGRESS, 'readonly');\n const store = tx.objectStore(STORE_RESTORE_PROGRESS);\n const index = store.index('device_status');\n const request = index.getAll(IDBKeyRange.only([deviceId, status]));\n request.onsuccess = () => {\n const records = ((request.result as RestoreProgressRecord[]) || []).filter(\n (record) => record.user_id === userId,\n );\n resolve(records);\n };\n request.onerror = () => reject(request.error);\n });\n }\n}\n","const AAD_DOMAIN = 'BBY_E2EE_MESSAGE_AAD';\nconst AAD_VERSION = 1;\n\nexport type E2eeMessageAadParams = {\n cid: string;\n e2ee_group_id: string;\n message_id: string;\n forward_cid?: string;\n forward_message_id?: string;\n forward_parent_cid?: string;\n e2ee_attachment_ids?: string[];\n};\n\nconst encoder = new TextEncoder();\n\nfunction writeU16(out: number[], value: number): void {\n if (!Number.isInteger(value) || value < 0 || value > 0xffff) {\n throw new Error(`u16 value out of range: ${value}`);\n }\n out.push((value >>> 8) & 0xff, value & 0xff);\n}\n\nfunction writeString(out: number[], value: string): void {\n const bytes = encoder.encode(value);\n writeU16(out, bytes.length);\n for (const byte of bytes) out.push(byte);\n}\n\nfunction writeOptionalString(out: number[], value?: string): void {\n if (value === undefined || value === null || value === '') {\n out.push(0);\n return;\n }\n out.push(1);\n writeString(out, value);\n}\n\nexport function uuidToRawBytes(uuid: string): Uint8Array {\n const hex = uuid.replace(/-/g, '').toLowerCase();\n if (!/^[0-9a-f]{32}$/.test(hex)) {\n throw new Error(`Invalid UUID: ${uuid}`);\n }\n const bytes = new Uint8Array(16);\n for (let i = 0; i < 16; i += 1) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nexport function compareUuidRaw(a: string, b: string): number {\n const ab = uuidToRawBytes(a);\n const bb = uuidToRawBytes(b);\n for (let i = 0; i < 16; i += 1) {\n if (ab[i] !== bb[i]) return ab[i] - bb[i];\n }\n return 0;\n}\n\nexport function canonicalAttachmentIds(ids?: string[]): string[] {\n if (!ids || ids.length === 0) return [];\n const seen = new Set<string>();\n const normalized = ids.map((id) => {\n const raw = uuidToRawBytes(id);\n const canonical = [...raw].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n if (seen.has(canonical)) {\n throw new Error(`Duplicate E2EE attachment id: ${id}`);\n }\n seen.add(canonical);\n return id;\n });\n return normalized.sort(compareUuidRaw);\n}\n\nexport function buildE2eeMessageAadV1(params: E2eeMessageAadParams): Uint8Array {\n const out: number[] = [];\n writeString(out, AAD_DOMAIN);\n out.push(AAD_VERSION);\n writeString(out, params.cid);\n writeString(out, params.e2ee_group_id);\n for (const byte of uuidToRawBytes(params.message_id)) out.push(byte);\n writeOptionalString(out, params.forward_cid);\n writeOptionalString(out, params.forward_message_id);\n writeOptionalString(out, params.forward_parent_cid);\n\n const attachmentIds = canonicalAttachmentIds(params.e2ee_attachment_ids);\n writeU16(out, attachmentIds.length);\n for (const id of attachmentIds) {\n for (const byte of uuidToRawBytes(id)) out.push(byte);\n }\n return new Uint8Array(out);\n}\n\nexport function hasE2eeAadMetadata(params: Partial<E2eeMessageAadParams>): boolean {\n return Boolean(\n (params.e2ee_attachment_ids && params.e2ee_attachment_ids.length > 0) ||\n params.forward_cid ||\n params.forward_message_id ||\n params.forward_parent_cid,\n );\n}\n\nexport function bytesEqual(a?: Uint8Array | null, b?: Uint8Array | null): boolean {\n if (!a || !b || a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i += 1) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n","import { sha256 } from '@noble/hashes/sha256';\nimport { bytesToHex } from '@noble/hashes/utils';\n\nfunction toBytes(data: Uint8Array | ArrayBuffer): Uint8Array {\n return data instanceof Uint8Array ? data : new Uint8Array(data);\n}\n\nexport class Sha256 {\n private hasher = sha256.create();\n private finished = false;\n\n update(data: Uint8Array | ArrayBuffer): this {\n if (this.finished) throw new Error('SHA-256 digest already finalized');\n this.hasher.update(toBytes(data));\n return this;\n }\n\n digest(): Uint8Array {\n if (this.finished) throw new Error('SHA-256 digest already finalized');\n this.finished = true;\n return this.hasher.digest();\n }\n\n hex(): string {\n return bytesToHex(this.digest());\n }\n}\n\nexport function sha256Hex(data: Uint8Array | ArrayBuffer): string {\n return new Sha256().update(data).hex();\n}\n","import { Sha256 } from './sha256';\n\nexport interface E2eeAttachmentHash {\n update(data: Uint8Array | ArrayBuffer): this;\n digest(): Uint8Array;\n hex(): string;\n}\n\nexport interface E2eeAttachmentCryptoProvider {\n randomBytes(length: number): Uint8Array;\n generateAesGcmKey(): Promise<Uint8Array> | Uint8Array;\n aesGcmEncrypt(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;\n aesGcmDecrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;\n createSha256(): E2eeAttachmentHash;\n}\n\nfunction getWebCrypto(): Crypto {\n const cryptoObj = globalThis.crypto;\n if (!cryptoObj?.subtle || !cryptoObj.getRandomValues) {\n throw new Error(\n 'Web Crypto API is required for the default E2EE attachment provider. React Native must inject attachmentCryptoProvider.',\n );\n }\n return cryptoObj;\n}\n\nfunction arrayBufferFrom(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.length);\n copy.set(bytes);\n return copy.buffer;\n}\n\nasync function importAesGcmKey(key: Uint8Array): Promise<CryptoKey> {\n return await getWebCrypto().subtle.importKey('raw', arrayBufferFrom(key), { name: 'AES-GCM' }, false, [\n 'encrypt',\n 'decrypt',\n ]);\n}\n\nexport const webE2eeAttachmentCryptoProvider: E2eeAttachmentCryptoProvider = {\n randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getWebCrypto().getRandomValues(bytes);\n return bytes;\n },\n\n generateAesGcmKey(): Uint8Array {\n return this.randomBytes(32);\n },\n\n async aesGcmEncrypt(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array> {\n const cryptoKey = await importAesGcmKey(key);\n return new Uint8Array(\n await getWebCrypto().subtle.encrypt({ name: 'AES-GCM', iv: arrayBufferFrom(nonce) }, cryptoKey, arrayBufferFrom(plaintext)),\n );\n },\n\n async aesGcmDecrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array> {\n const cryptoKey = await importAesGcmKey(key);\n return new Uint8Array(\n await getWebCrypto().subtle.decrypt(\n { name: 'AES-GCM', iv: arrayBufferFrom(nonce) },\n cryptoKey,\n arrayBufferFrom(ciphertext),\n ),\n );\n },\n\n createSha256(): E2eeAttachmentHash {\n return new Sha256();\n },\n};\n\nexport const defaultE2eeAttachmentCryptoProvider = webE2eeAttachmentCryptoProvider;\n","import type {\n E2eeAttachmentAssetKind,\n E2eeAttachmentManifest,\n E2eeAttachmentManifestAsset,\n InitE2eeAttachmentMultipartResponse,\n} from './types';\nimport { defaultE2eeAttachmentCryptoProvider, type E2eeAttachmentCryptoProvider } from './attachment_crypto_provider';\n\nexport const E2EE_ATTACHMENT_FRAME_SIZE = 256 * 1024;\nexport const E2EE_ATTACHMENT_PREVIEW_MAX_SIDE = 480;\nexport const E2EE_ATTACHMENT_PREVIEW_JPEG_QUALITY = 0.72;\nexport const E2EE_ATTACHMENT_VIDEO_PREVIEW_TIMEOUT_MS = 5000;\nexport const E2EE_ATTACHMENT_MULTIPART_UPLOAD_DEFAULT_CONCURRENCY = 3;\nexport const E2EE_ATTACHMENT_MULTIPART_UPLOAD_MAX_CONCURRENCY = 4;\nexport const E2EE_ATTACHMENT_MULTIPART_UPLOAD_URL_EXPIRY_SAFETY_MARGIN_MS = 120_000;\n\nexport type EncryptAssetOptions = {\n kind: E2eeAttachmentAssetKind;\n frameSize?: number;\n display?: Record<string, unknown>;\n cryptoProvider?: E2eeAttachmentCryptoProvider;\n onProgress?: (progress: { phase: 'encrypting'; loaded: number; total: number; percentage: number }) => void;\n};\n\nexport type EncryptedAsset = {\n kind: E2eeAttachmentAssetKind;\n encryptedBlob: Blob;\n cipher_size: number;\n cipher_sha256: string;\n frame_size: number;\n content_key: string;\n nonce_prefix: string;\n plaintext_size: number;\n plaintext_sha256: string;\n display?: Record<string, unknown>;\n};\n\nexport type EncryptedAssetMetadata = Omit<EncryptedAsset, 'encryptedBlob'>;\n\nexport type UploadedE2eeAttachment = {\n attachment_id: string;\n assets: E2eeAttachmentManifestAsset[];\n};\n\nexport type MultipartEncryptedAssetPart = {\n part_number: number;\n etag: string;\n};\n\nexport type MultipartEncryptedAssetUploadResult = {\n encrypted: EncryptedAssetMetadata;\n parts: MultipartEncryptedAssetPart[];\n};\n\nexport type EncryptMultipartAssetOptions = Omit<EncryptAssetOptions, 'onProgress'> & {\n multipart: InitE2eeAttachmentMultipartResponse;\n uploadConcurrency?: number;\n onProgress?: (progress: { phase: 'uploading'; loaded: number; total: number; percentage: number }) => void;\n signal?: AbortSignal;\n};\n\nexport type E2eeAttachmentTransferPhase = 'granting' | 'downloading' | 'verifying' | 'decrypting';\n\nexport type E2eeAttachmentTransferProgress = {\n phase: E2eeAttachmentTransferPhase;\n loaded: number;\n total: number;\n percentage?: number;\n};\n\nexport type E2eeAttachmentPreviewResult = {\n blob: Blob;\n originalWidth?: number;\n originalHeight?: number;\n previewWidth?: number;\n previewHeight?: number;\n duration?: number;\n};\n\nfunction isHeicLike(input: Blob & { name?: string }): boolean {\n const type = input.type.toLowerCase();\n const name = (input.name || '').toLowerCase();\n return type.includes('heic') || type.includes('heif') || name.endsWith('.heic') || name.endsWith('.heif');\n}\n\nfunction isBrowserPreviewAvailable(): boolean {\n return typeof document !== 'undefined' && typeof URL !== 'undefined' && typeof Blob !== 'undefined';\n}\n\nfunction scaledCanvasSize(width: number, height: number): { width: number; height: number } {\n if (width <= 0 || height <= 0) return { width: 1, height: 1 };\n const scale = Math.min(1, E2EE_ATTACHMENT_PREVIEW_MAX_SIDE / Math.max(width, height));\n return {\n width: Math.max(1, Math.round(width * scale)),\n height: Math.max(1, Math.round(height * scale)),\n };\n}\n\nfunction canvasToJpegBlob(canvas: HTMLCanvasElement): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) resolve(blob);\n else reject(new Error('E2EE attachment preview canvas produced no blob'));\n },\n 'image/jpeg',\n E2EE_ATTACHMENT_PREVIEW_JPEG_QUALITY,\n );\n });\n}\n\nfunction waitForElementEvent(element: HTMLElement, eventName: string, timeoutMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n reject(new Error(`E2EE attachment preview timed out waiting for ${eventName}`));\n }, timeoutMs);\n const onSuccess = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(`E2EE attachment preview failed on ${eventName}`));\n };\n const cleanup = () => {\n clearTimeout(timer);\n element.removeEventListener(eventName, onSuccess);\n element.removeEventListener('error', onError);\n };\n element.addEventListener(eventName, onSuccess, { once: true });\n element.addEventListener('error', onError, { once: true });\n });\n}\n\nasync function generateImagePreview(input: Blob): Promise<E2eeAttachmentPreviewResult> {\n const objectUrl = URL.createObjectURL(input);\n try {\n const image = new Image();\n image.decoding = 'async';\n image.src = objectUrl;\n await waitForElementEvent(image, 'load', E2EE_ATTACHMENT_VIDEO_PREVIEW_TIMEOUT_MS);\n const originalWidth = image.naturalWidth;\n const originalHeight = image.naturalHeight;\n const size = scaledCanvasSize(originalWidth, originalHeight);\n const canvas = document.createElement('canvas');\n canvas.width = size.width;\n canvas.height = size.height;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('E2EE attachment preview canvas context unavailable');\n ctx.drawImage(image, 0, 0, size.width, size.height);\n return {\n blob: await canvasToJpegBlob(canvas),\n originalWidth,\n originalHeight,\n previewWidth: size.width,\n previewHeight: size.height,\n };\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nasync function generateVideoPreview(input: Blob): Promise<E2eeAttachmentPreviewResult> {\n const objectUrl = URL.createObjectURL(input);\n const video = document.createElement('video');\n try {\n video.preload = 'metadata';\n video.muted = true;\n video.playsInline = true;\n video.src = objectUrl;\n await waitForElementEvent(video, 'loadedmetadata', E2EE_ATTACHMENT_VIDEO_PREVIEW_TIMEOUT_MS);\n if (!video.videoWidth || !video.videoHeight) {\n throw new Error('E2EE attachment video preview has no video track');\n }\n const duration = Number.isFinite(video.duration) && video.duration > 0 ? video.duration : 0;\n const seekTarget = Math.min(1, Math.max(0, duration * 0.1));\n if (seekTarget > 0) {\n video.currentTime = seekTarget;\n await waitForElementEvent(video, 'seeked', E2EE_ATTACHMENT_VIDEO_PREVIEW_TIMEOUT_MS);\n } else {\n await waitForElementEvent(video, 'loadeddata', E2EE_ATTACHMENT_VIDEO_PREVIEW_TIMEOUT_MS).catch(() => undefined);\n }\n const originalWidth = video.videoWidth;\n const originalHeight = video.videoHeight;\n const size = scaledCanvasSize(originalWidth, originalHeight);\n const canvas = document.createElement('canvas');\n canvas.width = size.width;\n canvas.height = size.height;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('E2EE attachment preview canvas context unavailable');\n ctx.drawImage(video, 0, 0, size.width, size.height);\n return {\n blob: await canvasToJpegBlob(canvas),\n originalWidth,\n originalHeight,\n previewWidth: size.width,\n previewHeight: size.height,\n duration: duration || undefined,\n };\n } finally {\n video.removeAttribute('src');\n video.load();\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nexport async function generateE2eeAttachmentPreview(\n input: Blob & { name?: string; type?: string },\n): Promise<E2eeAttachmentPreviewResult | undefined> {\n if (!isBrowserPreviewAvailable()) return undefined;\n if (isHeicLike(input)) return undefined;\n const type = input.type.toLowerCase();\n try {\n if (type.startsWith('image/')) return await generateImagePreview(input);\n if (type.startsWith('video/')) return await generateVideoPreview(input);\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nfunction writeU32(out: Uint8Array, offset: number, value: number): void {\n out[offset] = (value >>> 24) & 0xff;\n out[offset + 1] = (value >>> 16) & 0xff;\n out[offset + 2] = (value >>> 8) & 0xff;\n out[offset + 3] = value & 0xff;\n}\n\nfunction readU32(input: Uint8Array, offset: number): number {\n return ((input[offset] << 24) | (input[offset + 1] << 16) | (input[offset + 2] << 8) | input[offset + 3]) >>> 0;\n}\n\nfunction nonceForFrame(prefix: Uint8Array, frameIndex: number): Uint8Array {\n if (prefix.length !== 8) throw new Error('E2EE attachment nonce prefix must be 8 bytes');\n const nonce = new Uint8Array(12);\n nonce.set(prefix, 0);\n writeU32(nonce, 8, frameIndex);\n return nonce;\n}\n\nfunction arrayBufferFrom(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.length);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction concatUint8Arrays(chunks: Uint8Array[], totalLength: number): Uint8Array {\n const out = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.length;\n }\n return out;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction createAbortError(message: string): Error {\n const error = new Error(message);\n error.name = 'AbortError';\n return error;\n}\n\nclass NonRetryableMultipartUploadError extends Error {\n public readonly nonRetryable = true;\n\n public readonly code?: string;\n\n constructor(message: string, code?: string) {\n super(message);\n this.name = 'NonRetryableMultipartUploadError';\n this.code = code;\n }\n}\n\nfunction isNonRetryableMultipartUploadError(err: unknown): boolean {\n return Boolean((err as { nonRetryable?: boolean } | null)?.nonRetryable);\n}\n\nclass PresignedObjectUploadHttpError extends Error {\n public readonly status: number;\n\n constructor(status: number) {\n super(`E2EE attachment upload failed: HTTP ${status}`);\n this.name = 'PresignedObjectUploadHttpError';\n this.status = status;\n }\n}\n\nfunction uploadHttpStatus(err: unknown): number | undefined {\n return (err as { status?: number } | null)?.status;\n}\n\nexport function resolveE2eeAttachmentMultipartUploadConcurrency(value?: number): number {\n if (value === undefined) return E2EE_ATTACHMENT_MULTIPART_UPLOAD_DEFAULT_CONCURRENCY;\n if (!Number.isFinite(value) || value <= 0) return E2EE_ATTACHMENT_MULTIPART_UPLOAD_DEFAULT_CONCURRENCY;\n return Math.min(E2EE_ATTACHMENT_MULTIPART_UPLOAD_MAX_CONCURRENCY, Math.max(1, Math.floor(value)));\n}\n\nfunction parseAwsSigV4Date(value: string | null): number | undefined {\n if (!value) return undefined;\n const match = /^(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})Z$/.exec(value);\n if (!match) return undefined;\n const [, year, month, day, hour, minute, second] = match;\n const timestamp = Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n );\n return Number.isFinite(timestamp) ? timestamp : undefined;\n}\n\nexport function e2eeAttachmentMultipartUploadUrlExpiresAtMs(partUrl: string): number | undefined {\n try {\n const url = new URL(partUrl);\n const signedAt = parseAwsSigV4Date(url.searchParams.get('X-Amz-Date'));\n const expiresSecs = Number(url.searchParams.get('X-Amz-Expires'));\n if (signedAt === undefined || !Number.isFinite(expiresSecs) || expiresSecs <= 0) return undefined;\n return signedAt + expiresSecs * 1000;\n } catch {\n return undefined;\n }\n}\n\nfunction isE2eeAttachmentMultipartUploadUrlExpired(\n partUrl: string,\n nowMs: number = Date.now(),\n safetyMarginMs: number = E2EE_ATTACHMENT_MULTIPART_UPLOAD_URL_EXPIRY_SAFETY_MARGIN_MS,\n): boolean {\n const expiresAt = e2eeAttachmentMultipartUploadUrlExpiresAtMs(partUrl);\n return expiresAt !== undefined && nowMs + safetyMarginMs >= expiresAt;\n}\n\nfunction e2eeAttachmentUploadDebugEnabled(): boolean {\n const runtime = globalThis as typeof globalThis & {\n __ERMIS_E2EE_ATTACHMENT_UPLOAD_DEBUG__?: boolean;\n localStorage?: Storage;\n };\n if (runtime.__ERMIS_E2EE_ATTACHMENT_UPLOAD_DEBUG__ === true) return true;\n try {\n return runtime.localStorage?.getItem('ermis_e2ee_attachment_upload_debug') === '1';\n } catch {\n return false;\n }\n}\n\nfunction debugE2eeAttachmentUpload(event: string, details: Record<string, unknown>): void {\n if (!e2eeAttachmentUploadDebugEnabled()) return;\n try {\n console.debug('[Ermis E2EE attachment upload]', event, details);\n } catch {}\n}\n\nfunction multipartUploadUrlExpiredError(partNumber: number): NonRetryableMultipartUploadError {\n return new NonRetryableMultipartUploadError(\n `E2EE attachment multipart part ${partNumber} upload URL expired or is too close to expiry (multipart_upload_url_expired). Retry the attachment upload to obtain fresh presigned part URLs.`,\n 'multipart_upload_url_expired',\n );\n}\n\nfunction createLinkedAbortController(signal?: AbortSignal): AbortController {\n const controller = new AbortController();\n if (!signal) return controller;\n const abort = () => controller.abort();\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n return controller;\n}\n\nfunction throwIfMultipartUploadStopped(signal: AbortSignal, failure?: unknown): void {\n if (failure) throw failure;\n if (signal.aborted) throw createAbortError('E2EE attachment multipart upload aborted');\n}\n\ntype MultipartPartUploadProgress = (progress: {\n partNumber: number;\n loaded: number;\n total: number;\n attempt: number;\n}) => void;\n\ntype MultipartInFlightResult = { ok: true } | { ok: false; error: unknown };\n\nexport function estimateE2eeEncryptedAssetSize(\n plaintextSize: number,\n frameSize: number = E2EE_ATTACHMENT_FRAME_SIZE,\n): number {\n if (!Number.isFinite(plaintextSize) || plaintextSize < 0) {\n throw new Error('Invalid E2EE attachment plaintext size');\n }\n if (!Number.isFinite(frameSize) || frameSize <= 0) {\n throw new Error('Invalid E2EE attachment frame size');\n }\n const frameCount = Math.max(1, Math.ceil(plaintextSize / frameSize));\n return plaintextSize + frameCount * (8 + 16);\n}\n\nexport function bytesToBase64(bytes: Uint8Array): string {\n const bufferCtor = (\n globalThis as unknown as { Buffer?: { from(data: Uint8Array): { toString(enc: string): string } } }\n ).Buffer;\n if (bufferCtor) return bufferCtor.from(bytes).toString('base64');\n let binary = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n}\n\nexport function base64ToBytes(value: string): Uint8Array {\n const bufferCtor = (globalThis as unknown as { Buffer?: { from(data: string, enc: string): Uint8Array } }).Buffer;\n if (bufferCtor) return new Uint8Array(bufferCtor.from(value, 'base64'));\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\nexport function newUuid(cryptoProvider: E2eeAttachmentCryptoProvider = defaultE2eeAttachmentCryptoProvider): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID();\n const bytes = cryptoProvider.randomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport async function encryptE2eeAsset(input: Blob, options: EncryptAssetOptions): Promise<EncryptedAsset> {\n const cryptoProvider = options.cryptoProvider || defaultE2eeAttachmentCryptoProvider;\n const frameSize = options.frameSize || E2EE_ATTACHMENT_FRAME_SIZE;\n const rawKey = await cryptoProvider.generateAesGcmKey();\n const noncePrefix = cryptoProvider.randomBytes(8);\n\n const cipherHash = cryptoProvider.createSha256();\n const plainHash = cryptoProvider.createSha256();\n const parts: BlobPart[] = [];\n let offset = 0;\n let frameIndex = 0;\n\n while (offset < input.size || (input.size === 0 && frameIndex === 0)) {\n const end = input.size === 0 ? 0 : Math.min(offset + frameSize, input.size);\n const plain = new Uint8Array(await input.slice(offset, end).arrayBuffer());\n plainHash.update(plain);\n const cipher = await cryptoProvider.aesGcmEncrypt(rawKey, nonceForFrame(noncePrefix, frameIndex), plain);\n const header = new Uint8Array(8);\n writeU32(header, 0, plain.length);\n writeU32(header, 4, cipher.length);\n cipherHash.update(header).update(cipher);\n parts.push(arrayBufferFrom(header), arrayBufferFrom(cipher));\n offset = end;\n frameIndex += 1;\n options.onProgress?.({\n phase: 'encrypting',\n loaded: Math.min(offset, input.size),\n total: input.size,\n percentage: input.size === 0 ? 100 : Math.round((Math.min(offset, input.size) / input.size) * 100),\n });\n if (input.size === 0) break;\n }\n\n const encryptedBlob = new Blob(parts, { type: 'application/octet-stream' });\n return {\n kind: options.kind,\n encryptedBlob,\n cipher_size: encryptedBlob.size,\n cipher_sha256: cipherHash.hex(),\n frame_size: frameSize,\n content_key: bytesToBase64(rawKey),\n nonce_prefix: bytesToBase64(noncePrefix),\n plaintext_size: input.size,\n plaintext_sha256: plainHash.hex(),\n display: options.display,\n };\n}\n\nasync function uploadMultipartPartWithRetry(\n partUrl: string,\n partNumber: number,\n partBytes: Uint8Array,\n multipart: InitE2eeAttachmentMultipartResponse,\n onPartProgress?: MultipartPartUploadProgress,\n signal?: AbortSignal,\n): Promise<string> {\n const maxRetries = Math.max(0, multipart.max_part_retries || 0);\n const retryMaxElapsedMs = Math.max(1, multipart.retry_max_elapsed_secs || 900) * 1000;\n const startedAt = Date.now();\n let retryCount = 0;\n\n if (isE2eeAttachmentMultipartUploadUrlExpired(partUrl)) {\n throw multipartUploadUrlExpiredError(partNumber);\n }\n\n while (true) {\n throwIfMultipartUploadStopped(signal || new AbortController().signal);\n const attempt = retryCount + 1;\n const attemptStartedAt = Date.now();\n let partHighWater = 0;\n onPartProgress?.({ partNumber, loaded: 0, total: partBytes.length, attempt });\n debugE2eeAttachmentUpload('part_start', { part_number: partNumber, size_bytes: partBytes.length, attempt });\n try {\n const result = await putPresignedObjectWithResult(\n partUrl,\n new Blob([arrayBufferFrom(partBytes)], { type: 'application/octet-stream' }),\n (progress) => {\n partHighWater = Math.max(partHighWater, progress.loaded);\n onPartProgress?.({\n partNumber,\n loaded: Math.min(partHighWater, partBytes.length),\n total: partBytes.length,\n attempt,\n });\n },\n { readEtag: true, signal },\n );\n if (!result.etag) {\n throw new NonRetryableMultipartUploadError(\n `E2EE attachment multipart part ${partNumber} upload did not expose ETag. Configure R2 CORS ExposeHeaders to include ETag before enabling multipart.`,\n 'multipart_missing_etag',\n );\n }\n const durationMs = Math.max(1, Date.now() - attemptStartedAt);\n debugE2eeAttachmentUpload('part_complete', {\n part_number: partNumber,\n size_bytes: partBytes.length,\n attempt,\n duration_ms: durationMs,\n mbps: Number(((partBytes.length * 8) / durationMs / 1000).toFixed(2)),\n retry_count: retryCount,\n });\n return result.etag;\n } catch (err) {\n const status = uploadHttpStatus(err);\n if ((status === 401 || status === 403) && isE2eeAttachmentMultipartUploadUrlExpired(partUrl, Date.now(), 0)) {\n const expiredErr = multipartUploadUrlExpiredError(partNumber);\n debugE2eeAttachmentUpload('part_failed', {\n part_number: partNumber,\n attempt,\n status,\n retry_count: retryCount,\n reason: expiredErr.code,\n });\n throw expiredErr;\n }\n if (isNonRetryableMultipartUploadError(err)) throw err;\n if (signal?.aborted) throw err;\n const elapsed = Date.now() - startedAt;\n if (retryCount >= maxRetries || elapsed >= retryMaxElapsedMs) {\n debugE2eeAttachmentUpload('part_failed', {\n part_number: partNumber,\n attempt,\n status,\n retry_count: retryCount,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n throw err;\n }\n retryCount += 1;\n debugE2eeAttachmentUpload('part_retry', {\n part_number: partNumber,\n next_attempt: retryCount + 1,\n status,\n retry_count: retryCount,\n });\n const backoff = Math.min(30_000, 500 * 2 ** Math.min(retryCount, 6));\n await sleep(backoff + Math.floor(Math.random() * 250));\n }\n }\n}\n\nexport async function encryptAndUploadE2eeAssetMultipart(\n input: Blob,\n options: EncryptMultipartAssetOptions,\n): Promise<MultipartEncryptedAssetUploadResult> {\n const cryptoProvider = options.cryptoProvider || defaultE2eeAttachmentCryptoProvider;\n const frameSize = options.frameSize || E2EE_ATTACHMENT_FRAME_SIZE;\n const multipart = options.multipart;\n const uploadConcurrency = resolveE2eeAttachmentMultipartUploadConcurrency(options.uploadConcurrency);\n const partSize = multipart.part_size;\n if (!Number.isFinite(partSize) || partSize <= 0) {\n throw new Error('Invalid E2EE attachment multipart part size');\n }\n\n const totalCipherSize = estimateE2eeEncryptedAssetSize(input.size, frameSize);\n const expectedPartCount = Math.max(1, Math.ceil(totalCipherSize / partSize));\n if (multipart.part_count !== expectedPartCount) {\n throw new Error('E2EE attachment multipart part count mismatch');\n }\n\n const partUrls = new Map<number, string>();\n for (const part of multipart.parts || []) partUrls.set(part.part_number, part.put_url);\n\n const rawKey = await cryptoProvider.generateAesGcmKey();\n const noncePrefix = cryptoProvider.randomBytes(8);\n const cipherHash = cryptoProvider.createSha256();\n const plainHash = cryptoProvider.createSha256();\n const queueController = createLinkedAbortController(options.signal);\n const uploadedParts: MultipartEncryptedAssetPart[] = [];\n const inFlightUploads = new Map<number, Promise<MultipartInFlightResult>>();\n const inFlightProgress = new Map<number, number>();\n let firstUploadFailure: unknown;\n let completedBytes = 0;\n let lastEmittedUploadLoaded = 0;\n let nextPartNumberToSeal = 1;\n let partChunks: Uint8Array[] = [];\n let partLength = 0;\n\n const emitUploadProgress = () => {\n let inFlightLoaded = 0;\n for (const loaded of inFlightProgress.values()) inFlightLoaded += loaded;\n const loaded = Math.min(\n totalCipherSize,\n Math.max(lastEmittedUploadLoaded, completedBytes, completedBytes + inFlightLoaded),\n );\n lastEmittedUploadLoaded = loaded;\n options.onProgress?.({\n phase: 'uploading',\n loaded,\n total: totalCipherSize,\n percentage: totalCipherSize === 0 ? 100 : Math.round((loaded / totalCipherSize) * 100),\n });\n };\n\n const failAndDrain = async (err: unknown): Promise<never> => {\n firstUploadFailure = firstUploadFailure || err;\n if (!queueController.signal.aborted) queueController.abort();\n await Promise.all([...inFlightUploads.values()]);\n throw firstUploadFailure;\n };\n\n const waitForOneInFlight = async (): Promise<void> => {\n if (inFlightUploads.size === 0) return;\n const result = await Promise.race(inFlightUploads.values());\n if (!result.ok) await failAndDrain(result.error);\n };\n\n const waitForUploadCapacity = async (): Promise<void> => {\n while (inFlightUploads.size >= uploadConcurrency) await waitForOneInFlight();\n throwIfMultipartUploadStopped(queueController.signal, firstUploadFailure);\n };\n\n const enqueuePartUpload = async (partNumber: number, putUrl: string, partBytes: Uint8Array): Promise<void> => {\n await waitForUploadCapacity();\n inFlightProgress.set(partNumber, 0);\n const task = (async (): Promise<MultipartInFlightResult> => {\n try {\n const etag = await uploadMultipartPartWithRetry(\n putUrl,\n partNumber,\n partBytes,\n multipart,\n (progress) => {\n inFlightProgress.set(partNumber, Math.min(partBytes.length, progress.loaded));\n emitUploadProgress();\n },\n queueController.signal,\n );\n uploadedParts.push({ part_number: partNumber, etag });\n completedBytes += partBytes.length;\n inFlightProgress.delete(partNumber);\n emitUploadProgress();\n return { ok: true };\n } catch (error) {\n inFlightProgress.delete(partNumber);\n if (!queueController.signal.aborted) queueController.abort();\n firstUploadFailure = firstUploadFailure || error;\n emitUploadProgress();\n return { ok: false, error };\n } finally {\n inFlightUploads.delete(partNumber);\n }\n })();\n inFlightUploads.set(partNumber, task);\n };\n\n const flushPart = async (final: boolean) => {\n if (partLength === 0) return;\n throwIfMultipartUploadStopped(queueController.signal, firstUploadFailure);\n const partNumber = nextPartNumberToSeal;\n const putUrl = partUrls.get(partNumber);\n if (!putUrl) throw new Error(`E2EE attachment multipart missing upload URL for part ${partNumber}`);\n if (!final && partLength !== partSize) {\n throw new Error('E2EE attachment multipart attempted to flush a short non-final part');\n }\n const partBytes = concatUint8Arrays(partChunks, partLength);\n nextPartNumberToSeal += 1;\n partChunks = [];\n partLength = 0;\n await enqueuePartUpload(partNumber, putUrl, partBytes);\n };\n\n const appendEncryptedBytes = async (bytes: Uint8Array) => {\n let offset = 0;\n while (offset < bytes.length) {\n throwIfMultipartUploadStopped(queueController.signal, firstUploadFailure);\n const capacity = partSize - partLength;\n const take = Math.min(capacity, bytes.length - offset);\n partChunks.push(bytes.slice(offset, offset + take));\n partLength += take;\n offset += take;\n if (partLength === partSize) await flushPart(false);\n }\n };\n\n let offset = 0;\n let frameIndex = 0;\n while (offset < input.size || (input.size === 0 && frameIndex === 0)) {\n throwIfMultipartUploadStopped(queueController.signal, firstUploadFailure);\n const end = input.size === 0 ? 0 : Math.min(offset + frameSize, input.size);\n const plain = new Uint8Array(await input.slice(offset, end).arrayBuffer());\n plainHash.update(plain);\n const cipher = await cryptoProvider.aesGcmEncrypt(rawKey, nonceForFrame(noncePrefix, frameIndex), plain);\n const header = new Uint8Array(8);\n writeU32(header, 0, plain.length);\n writeU32(header, 4, cipher.length);\n cipherHash.update(header).update(cipher);\n await appendEncryptedBytes(header);\n await appendEncryptedBytes(cipher);\n offset = end;\n frameIndex += 1;\n throwIfMultipartUploadStopped(queueController.signal, firstUploadFailure);\n if (input.size === 0) break;\n }\n await flushPart(true);\n while (inFlightUploads.size > 0) await waitForOneInFlight();\n if (firstUploadFailure) await failAndDrain(firstUploadFailure);\n uploadedParts.sort((a, b) => a.part_number - b.part_number);\n\n if (uploadedParts.length !== multipart.part_count) {\n throw new Error('E2EE attachment multipart uploaded part count mismatch');\n }\n\n return {\n encrypted: {\n kind: options.kind,\n cipher_size: totalCipherSize,\n cipher_sha256: cipherHash.hex(),\n frame_size: frameSize,\n content_key: bytesToBase64(rawKey),\n nonce_prefix: bytesToBase64(noncePrefix),\n plaintext_size: input.size,\n plaintext_sha256: plainHash.hex(),\n display: options.display,\n },\n parts: uploadedParts,\n };\n}\n\nexport async function verifyEncryptedAssetHash(\n blob: Blob,\n expectedSha256: string,\n cryptoProvider: E2eeAttachmentCryptoProvider = defaultE2eeAttachmentCryptoProvider,\n onProgress?: (progress: E2eeAttachmentTransferProgress) => void,\n): Promise<void> {\n const hash = cryptoProvider.createSha256();\n let offset = 0;\n while (offset < blob.size) {\n const end = Math.min(offset + E2EE_ATTACHMENT_FRAME_SIZE, blob.size);\n hash.update(new Uint8Array(await blob.slice(offset, end).arrayBuffer()));\n offset = end;\n onProgress?.({\n phase: 'verifying',\n loaded: offset,\n total: blob.size,\n percentage: blob.size === 0 ? 100 : Math.round((offset / blob.size) * 100),\n });\n }\n if (blob.size === 0) {\n onProgress?.({ phase: 'verifying', loaded: 0, total: 0, percentage: 100 });\n }\n const actual = hash.hex();\n if (actual !== expectedSha256.toLowerCase()) {\n throw new Error('E2EE attachment ciphertext hash mismatch');\n }\n}\n\nexport async function decryptE2eeAsset(\n blob: Blob,\n manifest: E2eeAttachmentManifestAsset,\n cryptoProvider: E2eeAttachmentCryptoProvider = defaultE2eeAttachmentCryptoProvider,\n onProgress?: (progress: E2eeAttachmentTransferProgress) => void,\n): Promise<Blob> {\n await verifyEncryptedAssetHash(blob, manifest.cipher_sha256, cryptoProvider, onProgress);\n const rawKey = base64ToBytes(manifest.content_key);\n const noncePrefix = base64ToBytes(manifest.nonce_prefix);\n const parts: BlobPart[] = [];\n let offset = 0;\n let frameIndex = 0;\n let plainLoaded = 0;\n const plainTotal =\n typeof manifest.plaintext_size === 'number' && Number.isFinite(manifest.plaintext_size)\n ? manifest.plaintext_size\n : blob.size;\n\n while (offset < blob.size) {\n const header = new Uint8Array(await blob.slice(offset, offset + 8).arrayBuffer());\n if (header.length !== 8) throw new Error('Invalid E2EE attachment frame header');\n const plainLength = readU32(header, 0);\n const cipherLength = readU32(header, 4);\n offset += 8;\n const cipher = new Uint8Array(await blob.slice(offset, offset + cipherLength).arrayBuffer());\n if (cipher.length !== cipherLength) throw new Error('Invalid E2EE attachment frame body');\n const plain = await cryptoProvider.aesGcmDecrypt(rawKey, nonceForFrame(noncePrefix, frameIndex), cipher);\n if (plain.length !== plainLength) throw new Error('Invalid E2EE attachment plaintext frame length');\n parts.push(arrayBufferFrom(plain));\n offset += cipherLength;\n plainLoaded += plain.length;\n frameIndex += 1;\n onProgress?.({\n phase: 'decrypting',\n loaded: plainLoaded,\n total: plainTotal,\n percentage: plainTotal === 0 ? 100 : Math.round((plainLoaded / plainTotal) * 100),\n });\n }\n\n return new Blob(parts);\n}\n\nexport function buildManifestAsset(assetId: string, encrypted: EncryptedAssetMetadata): E2eeAttachmentManifestAsset {\n return {\n asset_id: assetId,\n kind: encrypted.kind,\n cipher_size: encrypted.cipher_size,\n cipher_sha256: encrypted.cipher_sha256,\n frame_size: encrypted.frame_size,\n content_key: encrypted.content_key,\n nonce_prefix: encrypted.nonce_prefix,\n plaintext_size: encrypted.plaintext_size,\n plaintext_sha256: encrypted.plaintext_sha256,\n display: encrypted.display,\n };\n}\n\nexport function buildAttachmentManifest(uploaded: UploadedE2eeAttachment): E2eeAttachmentManifest {\n return {\n version: 1,\n attachment_id: uploaded.attachment_id,\n assets: uploaded.assets,\n };\n}\n\nexport type PutPresignedObjectResult = {\n etag?: string;\n};\n\nexport async function putPresignedObjectWithResult(\n url: string,\n body: Blob,\n onProgress?: (progress: { phase: 'uploading'; loaded: number; total: number; percentage: number }) => void,\n options: { readEtag?: boolean; signal?: AbortSignal } = {},\n): Promise<PutPresignedObjectResult> {\n if (typeof XMLHttpRequest !== 'undefined') {\n return await new Promise<PutPresignedObjectResult>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n const abort = () => {\n xhr.abort();\n reject(createAbortError('E2EE attachment upload aborted'));\n };\n if (options.signal?.aborted) {\n abort();\n return;\n }\n options.signal?.addEventListener('abort', abort, { once: true });\n xhr.open('PUT', url);\n xhr.setRequestHeader('Content-Type', 'application/octet-stream');\n xhr.upload.onprogress = ({ loaded, total }) => {\n if (total > 0) {\n onProgress?.({ phase: 'uploading', loaded, total, percentage: Math.round((loaded / total) * 100) });\n }\n };\n xhr.onload = () => {\n options.signal?.removeEventListener('abort', abort);\n if (xhr.status < 300) {\n resolve({ etag: options.readEtag ? xhr.getResponseHeader('ETag') || undefined : undefined });\n } else {\n reject(new PresignedObjectUploadHttpError(xhr.status));\n }\n };\n xhr.onerror = () => {\n options.signal?.removeEventListener('abort', abort);\n reject(new Error('E2EE attachment upload network error'));\n };\n xhr.onabort = () => {\n options.signal?.removeEventListener('abort', abort);\n reject(createAbortError('E2EE attachment upload aborted'));\n };\n xhr.send(body);\n });\n }\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/octet-stream' },\n body,\n signal: options.signal,\n });\n if (!response.ok) throw new PresignedObjectUploadHttpError(response.status);\n return { etag: options.readEtag ? response.headers.get('ETag') || undefined : undefined };\n}\n\nexport async function putPresignedObject(\n url: string,\n body: Blob,\n onProgress?: (progress: { phase: 'uploading'; loaded: number; total: number; percentage: number }) => void,\n signal?: AbortSignal,\n): Promise<void> {\n await putPresignedObjectWithResult(url, body, onProgress, { signal });\n}\n\nexport async function downloadEncryptedAsset(\n url: string,\n onProgress?: (progress: E2eeAttachmentTransferProgress) => void,\n): Promise<Blob> {\n if (typeof XMLHttpRequest !== 'undefined') {\n return await new Promise<Blob>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', url);\n xhr.responseType = 'blob';\n xhr.onprogress = ({ loaded, total, lengthComputable }) => {\n onProgress?.({\n phase: 'downloading',\n loaded,\n total: lengthComputable && total > 0 ? total : 0,\n percentage: lengthComputable && total > 0 ? Math.round((loaded / total) * 100) : undefined,\n });\n };\n xhr.onload = () => {\n if (xhr.status < 300) {\n const blob = xhr.response instanceof Blob ? xhr.response : new Blob([xhr.response]);\n onProgress?.({ phase: 'downloading', loaded: blob.size, total: blob.size, percentage: 100 });\n resolve(blob);\n } else {\n reject(new Error(`E2EE attachment download failed: HTTP ${xhr.status}`));\n }\n };\n xhr.onerror = () => reject(new Error('E2EE attachment download network error'));\n xhr.send();\n });\n }\n const response = await fetch(url);\n if (!response.ok) throw new Error(`E2EE attachment download failed: HTTP ${response.status}`);\n const total = Number(response.headers.get('content-length') || 0);\n if (!response.body || typeof response.body.getReader !== 'function') {\n const blob = await response.blob();\n onProgress?.({ phase: 'downloading', loaded: blob.size, total: blob.size, percentage: 100 });\n return blob;\n }\n const reader = response.body.getReader();\n const chunks: BlobPart[] = [];\n let loaded = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(arrayBufferFrom(value));\n loaded += value.byteLength;\n onProgress?.({\n phase: 'downloading',\n loaded,\n total,\n percentage: total > 0 ? Math.round((loaded / total) * 100) : undefined,\n });\n }\n }\n return new Blob(chunks, { type: 'application/octet-stream' });\n}\n\nexport function ciphertextSha256(\n bytes: Uint8Array,\n cryptoProvider: E2eeAttachmentCryptoProvider = defaultE2eeAttachmentCryptoProvider,\n): string {\n return cryptoProvider.createSha256().update(bytes).hex();\n}\n","import type { DownloadE2eeAttachmentGrantResponse, E2eeAttachmentManifest, E2eeAttachmentManifestAsset } from './types';\n\nexport type E2eeMediaPlaybackStrategy = 'whole_blob' | 'native_range' | 'mse_fmp4';\n\nexport type E2eeMediaStreamWorkerOptions = {\n workerUrl?: string;\n scope?: string;\n enabled?: boolean;\n grantTtlMs?: number;\n safetyMarginMs?: number;\n rangeSmoke?: boolean;\n rangeSmokeTimeoutMs?: number;\n};\n\nexport type E2eeMediaStreamSessionOptions = E2eeMediaStreamWorkerOptions & {\n channelType: string;\n channelId: string;\n manifest: E2eeAttachmentManifest;\n kind?: 'original' | 'preview';\n mimeType?: string;\n renewGrant: () => Promise<DownloadE2eeAttachmentGrantResponse>;\n};\n\nexport type E2eeMediaStreamHandle = {\n sessionId: string;\n url: string;\n dispose: () => Promise<void>;\n};\n\ntype PendingRequest = {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype PageSession = {\n renewGrant: () => Promise<DownloadE2eeAttachmentGrantResponse>;\n grantTtlMs: number;\n safetyMarginMs: number;\n};\n\nconst DEFAULT_WORKER_URL = '/e2ee-media-stream-worker.js?v=20260702-3';\nconst DEFAULT_WORKER_SCOPE = '/';\nconst DEFAULT_GRANT_TTL_MS = 5 * 60 * 1000;\nconst DEFAULT_SAFETY_MARGIN_MS = 30 * 1000;\nconst VIRTUAL_PATH_PREFIX = '/__ermis/e2ee-media/';\nconst SMOKE_PATH = '/__ermis/e2ee-media-smoke';\nconst DEFAULT_RANGE_SMOKE_TIMEOUT_MS = 5000;\n\nlet registrationPromise: Promise<ServiceWorkerRegistration | null> | null = null;\nconst pending = new Map<string, PendingRequest>();\nconst pageSessions = new Map<string, PageSession>();\nlet messageListenerAttached = false;\n\nfunction randomId(): string {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID();\n return `stream-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction streamingFlagEnabled(explicit?: boolean): boolean {\n if (explicit !== undefined) return explicit;\n const globalValue = (globalThis as any).__ERMIS_E2EE_MEDIA_STREAMING_ENABLED__;\n if (globalValue === true || globalValue === '1') return true;\n try {\n return globalThis.localStorage?.getItem('ermis_e2ee_media_streaming') === '1';\n } catch {\n return false;\n }\n}\n\nfunction mseFlagEnabled(explicit?: boolean): boolean {\n if (explicit !== undefined) return explicit;\n const globalValue = (globalThis as any).__ERMIS_E2EE_MEDIA_MSE_ENABLED__;\n if (globalValue === true || globalValue === '1') return true;\n try {\n return globalThis.localStorage?.getItem('ermis_e2ee_media_mse') === '1';\n } catch {\n return false;\n }\n}\n\nfunction mediaStreamDebugEnabled(): boolean {\n const globalValue = (globalThis as any).__ERMIS_E2EE_MEDIA_PLAYBACK_DEBUG__;\n if (globalValue === true || globalValue === '1') return true;\n try {\n return (\n globalThis.localStorage?.getItem('ermis_e2ee_media_streaming_debug') === '1' ||\n globalThis.localStorage?.getItem('ermis_e2ee_media_playback_debug') === '1'\n );\n } catch {\n return false;\n }\n}\n\nfunction logMediaStreamFallback(reason: string, details?: unknown): void {\n if (!mediaStreamDebugEnabled()) return;\n if (details === undefined) console.info(`[E2EE media streaming] fallback: ${reason}`);\n else console.info(`[E2EE media streaming] fallback: ${reason}`, details);\n}\n\nexport function isE2eeMediaMsePlaybackEnabled(\n options: {\n streamingEnabled?: boolean;\n mseEnabled?: boolean;\n } = {},\n): boolean {\n return streamingFlagEnabled(options.streamingEnabled) && mseFlagEnabled(options.mseEnabled);\n}\n\nfunction isLikelyIosWebKit(userAgent: string): boolean {\n if (/iPad|iPhone|iPod/i.test(userAgent)) return true;\n const hasTouch = typeof globalThis !== 'undefined' && 'ontouchend' in globalThis;\n return /Macintosh/i.test(userAgent) && hasTouch;\n}\n\nexport function isE2eeMediaMsePlaybackAllowed(\n options: {\n streamingEnabled?: boolean;\n mseEnabled?: boolean;\n userAgent?: string;\n mediaSource?: { isTypeSupported?: (mimeType: string) => boolean };\n codecMimeType?: string;\n } = {},\n): boolean {\n if (!isE2eeMediaMsePlaybackEnabled(options)) return false;\n const userAgent = options.userAgent || (typeof navigator !== 'undefined' ? navigator.userAgent : '');\n if (isLikelyIosWebKit(userAgent)) return false;\n const mediaSource = options.mediaSource || (globalThis as any).MediaSource;\n if (!mediaSource || typeof mediaSource.isTypeSupported !== 'function') return false;\n if (options.codecMimeType) return mediaSource.isTypeSupported(options.codecMimeType);\n return true;\n}\n\nfunction waitForController(timeoutMs = 3000): Promise<boolean> {\n if (navigator.serviceWorker.controller) return Promise.resolve(true);\n return new Promise((resolve) => {\n const done = (value: boolean) => {\n clearTimeout(timeout);\n navigator.serviceWorker.removeEventListener('controllerchange', onControllerChange);\n resolve(value);\n };\n const onControllerChange = () => done(Boolean(navigator.serviceWorker.controller));\n const timeout = setTimeout(() => done(Boolean(navigator.serviceWorker.controller)), timeoutMs);\n navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);\n });\n}\n\nfunction postToWorker<T = unknown>(message: Record<string, unknown>, timeoutMs = 5000): Promise<T> {\n const controller = navigator.serviceWorker.controller;\n if (!controller) return Promise.reject(new Error('E2EE media stream worker is not controlling this page yet'));\n const requestId = randomId();\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n pending.delete(requestId);\n reject(new Error('E2EE media stream worker request timed out'));\n }, timeoutMs);\n pending.set(requestId, { resolve: resolve as (value: unknown) => void, reject, timeout });\n controller.postMessage({ ...message, requestId });\n });\n}\n\nfunction attachMessageListener(): void {\n if (messageListenerAttached || typeof navigator === 'undefined' || !navigator.serviceWorker) return;\n messageListenerAttached = true;\n navigator.serviceWorker.addEventListener('message', (event) => {\n const data = event.data || {};\n if (!data || typeof data !== 'object') return;\n if (data.type === 'ERMIS_E2EE_MEDIA_STREAM_ACK') {\n const request = pending.get(data.requestId);\n if (!request) return;\n pending.delete(data.requestId);\n clearTimeout(request.timeout);\n if (data.ok === false) request.reject(new Error(data.error || 'E2EE media stream worker request failed'));\n else request.resolve(data.payload);\n return;\n }\n if (data.type === 'ERMIS_E2EE_MEDIA_STREAM_RENEW_GRANT') {\n void handleGrantRenewal(String(data.sessionId || ''), String(data.requestId || ''));\n return;\n }\n if (data.type === 'ERMIS_E2EE_MEDIA_STREAM_ERROR') {\n logMediaStreamFallback('worker virtual URL failed', { url: data.url, range: data.range, error: data.error });\n }\n });\n}\n\nasync function handleGrantRenewal(sessionId: string, requestId: string): Promise<void> {\n const session = pageSessions.get(sessionId);\n const controller = navigator.serviceWorker.controller;\n if (!session || !controller) return;\n try {\n const grant = await session.renewGrant();\n controller.postMessage({\n type: 'ERMIS_E2EE_MEDIA_STREAM_GRANT_RENEWED',\n requestId,\n sessionId,\n grantUrl: grant.download_url,\n expiresAtMs: Date.now() + session.grantTtlMs,\n });\n } catch (err) {\n controller.postMessage({\n type: 'ERMIS_E2EE_MEDIA_STREAM_GRANT_FAILED',\n requestId,\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\nasync function registerWorker(options: E2eeMediaStreamWorkerOptions = {}): Promise<ServiceWorkerRegistration | null> {\n if (!streamingFlagEnabled(options.enabled)) {\n logMediaStreamFallback('feature flag is disabled');\n return null;\n }\n if (typeof window === 'undefined' || typeof navigator === 'undefined' || !('serviceWorker' in navigator)) {\n logMediaStreamFallback('Service Worker is unavailable');\n return null;\n }\n if (typeof ReadableStream === 'undefined' || !globalThis.crypto?.subtle) {\n logMediaStreamFallback('ReadableStream or WebCrypto is unavailable');\n return null;\n }\n attachMessageListener();\n const workerUrl = options.workerUrl || DEFAULT_WORKER_URL;\n const scope = options.scope || DEFAULT_WORKER_SCOPE;\n const registration = await navigator.serviceWorker.register(workerUrl, { scope });\n await navigator.serviceWorker.ready;\n if (!navigator.serviceWorker.controller) {\n const controlled = await waitForController();\n if (!controlled) {\n logMediaStreamFallback('Service Worker is registered but not controlling this page yet');\n return null;\n }\n }\n await postToWorker({ type: 'ERMIS_E2EE_MEDIA_STREAM_PING' }, 3000);\n const smoke = await fetch(`${SMOKE_PATH}?t=${Date.now()}`, { cache: 'no-store' });\n if (smoke.status !== 204) {\n logMediaStreamFallback('virtual smoke route was not intercepted', { status: smoke.status });\n return null;\n }\n return registration;\n}\n\nexport async function ensureE2eeMediaStreamWorker(options: E2eeMediaStreamWorkerOptions = {}): Promise<boolean> {\n if (!registrationPromise) {\n registrationPromise = registerWorker(options).catch((err) => {\n logMediaStreamFallback('worker registration failed', err instanceof Error ? err.message : String(err));\n return null;\n });\n }\n const registration = await registrationPromise;\n const ready = Boolean(registration && navigator.serviceWorker.controller);\n if (!ready) registrationPromise = null;\n return ready;\n}\n\nfunction selectAsset(\n manifest: E2eeAttachmentManifest,\n kind: 'original' | 'preview',\n): E2eeAttachmentManifestAsset | undefined {\n return manifest.assets.find((asset) => asset.kind === kind) || (kind === 'original' ? manifest.assets[0] : undefined);\n}\n\nfunction displayString(asset: E2eeAttachmentManifestAsset | undefined, key: string): string | undefined {\n const value = asset?.display?.[key];\n return typeof value === 'string' && value ? value : undefined;\n}\n\nasync function smokeTestR2Range(\n downloadUrl: string,\n timeoutMs = DEFAULT_RANGE_SMOKE_TIMEOUT_MS,\n): Promise<{ ok: boolean; status?: number; error?: string }> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(downloadUrl, {\n headers: { Range: 'bytes=0-0' },\n cache: 'no-store',\n signal: controller.signal,\n });\n return { ok: response.status === 206, status: response.status };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n } finally {\n clearTimeout(timeout);\n controller.abort();\n }\n}\n\nexport async function createE2eeAttachmentStreamUrl(\n options: E2eeMediaStreamSessionOptions,\n): Promise<E2eeMediaStreamHandle | null> {\n const kind = options.kind || 'original';\n if (kind !== 'original') {\n logMediaStreamFallback('only original assets are streamable', { kind });\n return null;\n }\n const asset = selectAsset(options.manifest, kind);\n if (!asset) {\n logMediaStreamFallback('manifest has no original asset');\n return null;\n }\n const mimeType = options.mimeType || displayString(asset, 'mime_type') || 'application/octet-stream';\n if (!mimeType.toLowerCase().startsWith('video/')) {\n logMediaStreamFallback('asset is not a video', { mimeType });\n return null;\n }\n const ready = await ensureE2eeMediaStreamWorker(options);\n if (!ready) return null;\n\n const grantTtlMs = options.grantTtlMs || DEFAULT_GRANT_TTL_MS;\n const safetyMarginMs = options.safetyMarginMs || DEFAULT_SAFETY_MARGIN_MS;\n const grant = await options.renewGrant();\n if (options.rangeSmoke !== false) {\n const rangeSmoke = await smokeTestR2Range(grant.download_url, options.rangeSmokeTimeoutMs);\n if (!rangeSmoke.ok) {\n logMediaStreamFallback('R2 range smoke failed', rangeSmoke);\n return null;\n }\n }\n const sessionId = randomId();\n pageSessions.set(sessionId, {\n renewGrant: options.renewGrant,\n grantTtlMs,\n safetyMarginMs,\n });\n const plaintextSize = typeof asset.plaintext_size === 'number' ? asset.plaintext_size : undefined;\n if (plaintextSize === undefined || plaintextSize < 0) {\n pageSessions.delete(sessionId);\n logMediaStreamFallback('manifest is missing plaintext_size');\n return null;\n }\n\n try {\n await postToWorker({\n type: 'ERMIS_E2EE_MEDIA_STREAM_CREATE_SESSION',\n session: {\n sessionId,\n grantUrl: grant.download_url,\n expiresAtMs: Date.now() + grantTtlMs,\n safetyMarginMs,\n mimeType,\n plaintextSize,\n cipherSize: asset.cipher_size,\n frameSize: asset.frame_size || 256 * 1024,\n contentKey: asset.content_key,\n noncePrefix: asset.nonce_prefix,\n assetId: asset.asset_id,\n attachmentId: options.manifest.attachment_id,\n },\n });\n await postToWorker(\n { type: 'ERMIS_E2EE_MEDIA_STREAM_TEST_SESSION', sessionId },\n options.rangeSmokeTimeoutMs || 5000,\n );\n } catch (err) {\n pageSessions.delete(sessionId);\n logMediaStreamFallback('worker session test failed', err instanceof Error ? err.message : String(err));\n try {\n await postToWorker({ type: 'ERMIS_E2EE_MEDIA_STREAM_DISPOSE_SESSION', sessionId }, 2000);\n } catch {\n // Best-effort cleanup; worker idle expiry is the crash-safety net.\n }\n return null;\n }\n\n return {\n sessionId,\n url: `${VIRTUAL_PATH_PREFIX}${encodeURIComponent(sessionId)}`,\n dispose: async () => {\n await disposeE2eeAttachmentStreamUrl(sessionId);\n },\n };\n}\n\nexport async function disposeE2eeAttachmentStreamUrl(sessionId: string): Promise<void> {\n pageSessions.delete(sessionId);\n if (typeof navigator === 'undefined' || !navigator.serviceWorker?.controller) return;\n try {\n await postToWorker({ type: 'ERMIS_E2EE_MEDIA_STREAM_DISPOSE_SESSION', sessionId }, 2000);\n } catch {\n // Disposal is best-effort; worker idle expiry is the crash-safety net.\n }\n}\n\nexport async function disposeAllE2eeAttachmentStreamSessions(): Promise<void> {\n pageSessions.clear();\n if (typeof navigator === 'undefined' || !navigator.serviceWorker?.controller) return;\n try {\n await postToWorker({ type: 'ERMIS_E2EE_MEDIA_STREAM_DISPOSE_ALL' }, 2000);\n } catch {\n // Best-effort cleanup; worker sessions still expire on idle timeout.\n }\n}\n","/**\n * Encryption Manager — Manages encryption (E2EE) state for Ermis Chat\n *\n * Handles:\n * - WASM initialization (openmls-wasm)\n * - Identity creation/restore\n * - encryption group cache + persistence via storage adapter\n * - E2eeClient wrapper for API calls\n * - Encrypt/decrypt operations\n * - Protocol event processing (commits, welcomes)\n * - Offline sync\n * - Epoch-stale retry (server rejects stale commits → clear + sync + retry)\n */\n\nimport { E2eeClient } from './api';\nimport { IndexedDBEncryptionStorage } from './storage';\nimport type {\n ArchiveBlobRecord,\n ArchiveKeyWrapRecord,\n ArchiveScope,\n BootstrapKnownE2eeChannelsOptions,\n BootstrapKnownE2eeChannelsResult,\n ChannelRepairState,\n CiphertextCursor,\n DecryptResult,\n E2eeAttachmentManifest,\n E2eeBootstrapProgress,\n E2eeBootstrapStatus,\n E2eePayload,\n E2eeStoredMessage,\n E2eeSyncState,\n E2eeSyncStatus,\n EncryptedChannelRepairMode,\n EncryptedChannelRepairResult,\n EpochArchiveCheckpoint,\n EnsureE2eeChannelResult,\n EventCursor,\n HistoricalCiphertext,\n EncryptionManagerOptions,\n EncryptionStorageAdapter,\n PendingArchiveUpload,\n PendingDeferredArchive,\n PendingE2eeSendRecord,\n PendingE2eeSendStatus,\n PendingE2eeSnapshot,\n QueryEpochArchivesResponse,\n QueryE2eeAttachmentProjection,\n QueryE2eeAttachmentsRequest,\n CompleteE2eeAttachmentRequest,\n InitE2eeAttachmentAssetResponse,\n RecoveryStatus,\n RecoveryVaultResponse,\n RemovedSyncCursor,\n RepairIssue,\n RepairIssueReason,\n RepairIssueStatus,\n RepairMessageResult,\n RepairMode,\n RepairResult,\n RestorePermanentGapReason,\n RestoreProgressRecord,\n RestoreStatus,\n RestoreTransientFailureReason,\n RestoredMessage,\n UploadEpochArchiveRequest,\n WaterfallResult,\n} from './types';\nimport { buildE2eeMessageAadV1, bytesEqual, canonicalAttachmentIds, hasE2eeAadMetadata } from './aad';\nimport {\n buildAttachmentManifest,\n buildManifestAsset,\n ciphertextSha256,\n decryptE2eeAsset,\n downloadEncryptedAsset,\n encryptAndUploadE2eeAssetMultipart,\n encryptE2eeAsset,\n estimateE2eeEncryptedAssetSize,\n generateE2eeAttachmentPreview,\n newUuid,\n putPresignedObject,\n resolveE2eeAttachmentMultipartUploadConcurrency,\n type E2eeAttachmentTransferProgress,\n} from './attachments';\nimport { defaultE2eeAttachmentCryptoProvider, type E2eeAttachmentCryptoProvider } from './attachment_crypto_provider';\nimport {\n createE2eeAttachmentStreamUrl,\n type E2eeMediaStreamHandle,\n type E2eeMediaStreamWorkerOptions,\n} from './e2ee_media_stream';\nimport type { ErmisChat } from '../client';\nimport type { ExtendableGenerics, DefaultGenerics, E2eeRecoveryPolicy } from '../types';\nimport { sdkLog } from '../logger';\nimport { getUserInfo, pickUserWithDisplayName } from '../utils';\n\n// ============================================================\n// Epoch-stale error detection\n// ============================================================\n\n/** Check if an API error is an epoch_stale rejection from bellboy. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isEpochStaleError(err: any): boolean {\n const msg = err?.message || err?.response?.data?.message || String(err);\n return msg.includes('epoch_stale');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isE2eeAttachmentInvalidError(err: any): boolean {\n const data = err?.response?.data || err?.data || err;\n const reason = typeof data?.reason === 'string' ? data.reason : '';\n const message =\n typeof data?.message === 'string' ? data.message : typeof err?.message === 'string' ? err.message : '';\n return reason === 'e2ee_attachment_invalid' || message.includes('e2ee_attachment_invalid');\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getApiErrorMessage(err: any): string {\n return String(err?.response?.data?.message || err?.message || err || '');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getApiErrorCode(err: any): number | undefined {\n const raw = err?.response?.data?.ermis_code ?? err?.response?.data?.code ?? err?.ermis_code ?? err?.code;\n const code = Number(raw);\n return Number.isFinite(code) ? code : undefined;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isRetryableRecoveryNetworkError(err: any): boolean {\n const status = Number(err?.response?.status ?? err?.status);\n if (!Number.isFinite(status) || status <= 0) return true;\n return status === 408 || status === 429 || status >= 500;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isVaultMissingError(err: any): boolean {\n const status = err?.response?.status || err?.status;\n const msg = getApiErrorMessage(err).toLowerCase();\n return status === 404 || msg.includes('recovery vault not found');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getActiveTargetFromCommitEvictionError(err: any): string | undefined {\n const msg = getApiErrorMessage(err);\n const match = msg.match(/target_user_id\\s+(\\S+)\\s+is still an active channel member/);\n return match?.[1];\n}\n\nfunction normalizeRfc3339Cursor(value: string): string {\n const match = value.match(/^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(?:\\.(\\d+))?Z$/);\n if (!match) return value;\n return `${match[1]}.${(match[2] || '').padEnd(9, '0').slice(0, 9)}Z`;\n}\n\nfunction compareRfc3339Cursor(a?: string | null, b?: string | null): number {\n if (!a && !b) return 0;\n if (!a) return -1;\n if (!b) return 1;\n const left = normalizeRfc3339Cursor(a);\n const right = normalizeRfc3339Cursor(b);\n if (left === right) return 0;\n return left > right ? 1 : -1;\n}\n\nconst ZERO_EVENT_ID = '00000000-0000-0000-0000-000000000000';\n\nfunction compareEventCursor(a?: EventCursor | null, b?: EventCursor | null): number {\n if (!a && !b) return 0;\n if (!a) return -1;\n if (!b) return 1;\n const createdAtCmp = compareRfc3339Cursor(a.created_at, b.created_at);\n if (createdAtCmp !== 0) return createdAtCmp;\n if (a.event_id === b.event_id) return 0;\n return a.event_id > b.event_id ? 1 : -1;\n}\n\nfunction isRemovedCursorAfter(next: RemovedSyncCursor, current?: RemovedSyncCursor | null): boolean {\n if (!current) return true;\n const removedAtCmp = compareRfc3339Cursor(next.removed_at, current.removed_at);\n if (removedAtCmp !== 0) return removedAtCmp > 0;\n return next.event_id > current.event_id;\n}\n\nfunction staleGroupInfoError(cid: string): Error & { code: string } {\n const err = new Error(\n `[Encryption] GroupInfo is stale for ${cid}; retry after an existing member uploads fresh GroupInfo`,\n ) as Error & { code: string };\n err.code = 'stale_group_info';\n return err;\n}\n\nconst KEY_PACKAGE_POOL_TARGET = 100;\nconst RESTORE_EPOCH_BATCH_SIZE = 25;\nconst RESTORE_EPOCH_MAX_SPAN = 100;\nconst RESTORE_DECRYPT_MAX_RETRIES = 3;\nconst RESTORE_NETWORK_MAX_RETRIES = 5;\nconst CHANNEL_REPAIR_LOCK_TTL_MS = 60_000;\nconst ENCRYPTION_EXPECTED_DECRYPT_LOG_TTL_MS = 60_000;\nconst ENCRYPTION_WATERFALL_SUMMARY_LOG_TTL_MS = 10_000;\nconst RECENT_INVITE_ACCEPT_RESTORE_PROMPT_GRACE_MS = 2 * 60_000;\nconst CHANNEL_REPAIR_RESET_THRESHOLD = 3;\n\nfunction cidFromParts(channelType: string, channelId: string): string {\n return `${channelType}:${channelId}`;\n}\n\nfunction channelPartsFromCid(cid: string): { channelType: string; channelId: string } | null {\n const colonIdx = cid.indexOf(':');\n if (colonIdx < 0) return null;\n return {\n channelType: cid.substring(0, colonIdx),\n channelId: cid.substring(colonIdx + 1),\n };\n}\n\nfunction splitRestoreEpochBatches(epochs: number[]): number[][] {\n const batches: number[][] = [];\n let current: number[] = [];\n let startEpoch: number | null = null;\n\n for (const epoch of epochs) {\n if (current.length === 0) {\n current = [epoch];\n startEpoch = epoch;\n continue;\n }\n\n const span = epoch - (startEpoch ?? epoch);\n if (current.length >= RESTORE_EPOCH_BATCH_SIZE || span > RESTORE_EPOCH_MAX_SPAN) {\n batches.push(current);\n current = [epoch];\n startEpoch = epoch;\n continue;\n }\n\n current.push(epoch);\n }\n\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\nfunction bytesToHex(bytes: Uint8Array | number[]): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nfunction toEpochBigInt(epoch: number | bigint): bigint {\n return typeof epoch === 'bigint' ? epoch : BigInt(epoch);\n}\n\nfunction newArchiveBlobId(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID();\n }\n return `archive-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\ninterface RestoreQueueEntry {\n cid: string;\n channelType: string;\n channelId: string;\n priority: 'active' | 'background';\n options?: { fromEpoch?: number; toEpoch?: number };\n}\n\ninterface RestoreExecutionOptions {\n fromEpoch?: number;\n toEpoch?: number;\n forceRecheck?: boolean;\n manualRepair?: boolean;\n timelineOnly?: boolean;\n targetEpochs?: number[];\n messageIds?: Set<string>;\n}\n\ninterface ChannelProcessResult {\n processedEventCursor?: EventCursor;\n processedEvents: number;\n bufferedMessages: number;\n decrypted: E2eeStoredMessage[];\n maxObservedEpoch?: number;\n}\n\ntype ActiveMessageEnvelope = Record<string, unknown> & {\n id: string;\n user?: { id: string; [key: string]: unknown };\n user_id?: string;\n created_at?: string | Date;\n updated_at?: string | Date | null;\n mls_epoch?: number;\n};\n\ntype ArchiveMessageEnvelope = Record<string, unknown> & {\n id: string;\n user?: { id: string; [key: string]: unknown };\n user_id?: string;\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n};\n\ntype QueuedE2eeAttachmentProgress = {\n fileIndex: number;\n phase: 'generating_preview' | 'encrypting' | 'uploading' | 'completing' | 'sending';\n loaded: number;\n total: number;\n percentage: number;\n};\n\ntype QueuedE2eeAttachmentSendParams = {\n channelType: string;\n channelId: string;\n cid: string;\n text: string;\n messageId: string;\n files: Blob[];\n options?: {\n parent_id?: string;\n quoted_message_id?: string;\n mentioned_users?: string[];\n mentioned_all?: boolean;\n forward_cid?: string;\n forward_message_id?: string;\n forward_parent_cid?: string;\n };\n displayOverrides?: Map<number, Record<string, unknown>>;\n localAttachments?: unknown[];\n onProgress?: (progress: QueuedE2eeAttachmentProgress) => void;\n onSuccess?: (response: any) => void;\n onError?: (error: unknown) => void;\n};\n\n// WASM module — loaded dynamically\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet wasmModule: any = null;\n\n// ============================================================\n// Encryption Manager Class\n// ============================================================\n\n/**\n * Encryption Manager — instantiate and call `initialize()` to set up E2EE.\n *\n * @example\n * ```ts\n * import { EncryptionManager } from '@ermis-network/ermis-chat-sdk';\n *\n * const encryptionManager = new EncryptionManager();\n * await encryptionManager.initialize(client, userId, {\n * wasmPath: '/openmls_wasm_bg.wasm',\n * });\n * ```\n */\nexport class EncryptionManager<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n initialized = false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provider: any = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n identity: any = null;\n userId: string | null = null;\n deviceId: string | null = null;\n e2eeClient: E2eeClient<ErmisChatGenerics> | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n client: ErmisChat<ErmisChatGenerics> | null = null;\n storage: EncryptionStorageAdapter;\n\n /** cid → Group (WASM object) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n groups: Map<string, any> = new Map();\n\n /** Whether Provider was restored from storage (vs newly created) */\n private _providerRestored = false;\n private _wasmPath = '/openmls_wasm_bg.wasm';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _injectedWasm: any = null;\n\n /** Sync state tracking — used to gate WS decryption during reconnect sync */\n private _syncing = false;\n private _syncPromise: Promise<void> | null = null;\n private _syncWorkPromise: Promise<void> | null = null;\n private _keyPackageUploadPromise: Promise<void> | null = null;\n private _syncGateResolve: (() => void) | null = null;\n private _lastSyncStates: Map<string, E2eeSyncState> = new Map();\n private _scopeRepairLocks: Map<string, Promise<EncryptedChannelRepairResult>> = new Map();\n private _scopeRepairGateResolvers: Map<string, () => void> = new Map();\n private _scopeRepairGatePromises: Map<string, Promise<void>> = new Map();\n private _scopeSyncRequestedAfterRepair: Set<string> = new Set();\n private readonly _repairLockOwnerId = `repair-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n private _channelReadyLocks: Map<string, Promise<EnsureE2eeChannelResult>> = new Map();\n private _channelReadyUntil: Map<string, number> = new Map();\n private readonly _channelReadyCacheMs = 30_000;\n private _recoveryPrivateKey: Uint8Array | null = null;\n private _recoveryPublicKey: Uint8Array | null = null;\n private _recoveryKeyId: string | null = null;\n private _recoveryCiphersuite: number | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _wrappedRecoveryKey: any = null;\n private _recoveryVaultKnown: boolean | null = null;\n private _recoveryVaultBytes: Uint8Array | null = null;\n private _recoveryVaultRevision: number | null = null;\n private _recoveryPublicMetadataPromise: Promise<RecoveryVaultResponse | null> | null = null;\n private _recoveryRecheckDoneForUnlock = false;\n private _recoveryPostUnlockMaintenancePromise: Promise<void> | null = null;\n private _recoveryPostUnlockMaintenanceGeneration = 0;\n private _archiveStashKey: CryptoKey | null = null;\n private _archiveStashKeyPromise: Promise<CryptoKey> | null = null;\n private _archiveCheckpointMaterializations = new Map<string, Promise<void>>();\n private _sponsoredArchiveDisabled = false;\n private _expectedDecryptLogKeys = new Map<string, number>();\n private _waterfallSummaryLogKeys = new Map<string, number>();\n private _deferredEncryptionEventLogKeys = new Map<string, number>();\n private _attachmentCryptoProvider: E2eeAttachmentCryptoProvider = defaultE2eeAttachmentCryptoProvider;\n private _e2eeAttachmentMultipartEnabled = false;\n private _e2eeAttachmentMultipartUploadConcurrency = resolveE2eeAttachmentMultipartUploadConcurrency();\n private _e2eeSendLockChains: Map<string, Promise<void>> = new Map();\n private _pendingE2eeSendJobs: Set<string> = new Set();\n private _pendingE2eeSendAbortControllers: Map<string, AbortController> = new Map();\n private _canceledPendingE2eeSends: Set<string> = new Set();\n private _restoreQueue: RestoreQueueEntry[] = [];\n private _restoreQueueRunning = false;\n private _restoreInflight = new Map<string, Promise<RestoredMessage[]>>();\n private _bootstrapKnownChannelsPromise: Promise<BootstrapKnownE2eeChannelsResult> | null = null;\n private _channelBootstrapSub: { unsubscribe?: () => void } | null = null;\n private _e2eeBootstrapProgress: E2eeBootstrapProgress = {\n total: 0,\n completed: 0,\n failed_cids: [],\n status: 'idle',\n };\n\n /**\n * Deferred eviction queue — populated during sync when a MemberLeaved system message\n * (type 12) is seen. Drained AFTER the sync loop completes so the epoch is fully\n * up-to-date before we create a commit.\n *\n * Map: cid → Set of user_ids to evict\n */\n private _pendingEvictions: Map<string, Set<string>> = new Map();\n\n /**\n * In-memory dedup: message IDs already decrypted in this session.\n * Prevents race condition where waterfall decrypt (sync) consumes ratchet\n * secrets but IndexedDB write hasn't flushed before WS message.new event\n * triggers processE2eeMessage(). Without this, processE2eeMessage would\n * attempt re-decryption → SecretReuseError (forward secrecy).\n */\n private _decryptedMsgIds = new Set<string>();\n\n constructor() {\n // Storage is created in initialize() with the userId for user-scoped DB.\n // Use a temporary placeholder; callers must call initialize() before use.\n this.storage = null as unknown as EncryptionStorageAdapter;\n }\n\n // ============================================================\n // Initialization\n // ============================================================\n\n /**\n * Initialize the encryption manager\n * @param client - SDK client instance\n * @param userId - Current user ID\n * @param options - Optional storage adapter and WASM path\n */\n async initialize(\n client: ErmisChat<ErmisChatGenerics>,\n userId: string,\n options?: EncryptionManagerOptions,\n ): Promise<void> {\n if (this.initialized) return;\n\n this.client = client;\n this.userId = userId;\n\n if (options?.storage) {\n this.storage = options.storage;\n } else {\n // User-scoped storage: each user gets their own IndexedDB database\n this.storage = new IndexedDBEncryptionStorage(userId);\n }\n if (options?.wasmPath) {\n this._wasmPath = options.wasmPath;\n }\n if (options?.wasmModule) {\n this._injectedWasm = options.wasmModule;\n }\n if (options?.enableSponsoredArchives === false) {\n this._sponsoredArchiveDisabled = true;\n }\n if (options?.attachmentCryptoProvider) {\n this._attachmentCryptoProvider = options.attachmentCryptoProvider;\n }\n this._e2eeAttachmentMultipartEnabled = options?.enableE2eeAttachmentMultipart === true;\n this._e2eeAttachmentMultipartUploadConcurrency = resolveE2eeAttachmentMultipartUploadConcurrency(\n options?.e2eeAttachmentMultipartUploadConcurrency,\n );\n\n // Reuse deviceId if already eagerly initialized in connectUser(),\n // otherwise fall back to storage (e.g., non-browser or custom flow).\n if ((this.client as any).deviceId) {\n this.deviceId = (this.client as any).deviceId;\n } else {\n this.deviceId = await this.storage.getDeviceId();\n // Propagate back to client so WS reconnects and HTTP headers include it\n (this.client as any).deviceId = this.deviceId;\n }\n\n // 1. Load WASM + restore or create Provider\n await this._initWasm();\n\n // 2. Create or restore Identity\n await this._initIdentity();\n\n // 3. Create E2eeClient\n this.e2eeClient = new E2eeClient<ErmisChatGenerics>(client);\n\n // Load public recovery metadata before sync so this device can upload\n // account-owned archives without requiring the user to enter the PIN first.\n await this._loadRecoveryPublicMetadata().catch((err) => {\n sdkLog('warn', '[Encryption] Recovery public metadata unavailable during init:', err);\n });\n\n // Normalize interrupted restore jobs before status/UI checks.\n await this._normalizeStaleRestoreProgress();\n\n // 4. Top up this device's server-side KeyPackage pool on every init.\n // Prefer the latest health.check count when it arrived before encryption init;\n // only query the count endpoint when no health.check count is cached.\n await this.ensureKeyPackagesFromCachedHealthOrServer();\n\n // 5. Sync encryption events for E2EE channels (restore groups from server)\n await this._syncAndRestoreGroups();\n\n // 6. Persist Provider snapshot after sync (groups modify the key store)\n await this._persistProvider();\n\n // 7. Register this manager on the client so event handlers can access it\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any).encryptionManager = this;\n this._registerKnownChannelBootstrapListener();\n\n this.initialized = true;\n void this._resumeEpochArchiveCheckpoints();\n void this.resumePendingE2eeSends();\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.initialized',\n user_id: this.userId,\n device_id: this.deviceId,\n } as any);\n sdkLog('info', '[Encryption] Manager initialized', {\n userId: this.userId,\n deviceId: this.deviceId,\n groups: this.groups.size,\n });\n }\n\n /**\n * Load WASM module and restore or create Provider.\n *\n * The Provider holds the key store (private keys for KPs, groups, etc).\n * If previously saved to storage, restore it to preserve existing KPs.\n */\n private async _initWasm(): Promise<void> {\n if (wasmModule) {\n // WASM already loaded, just restore Provider\n await this._restoreOrCreateProvider();\n return;\n }\n\n if (this._injectedWasm) {\n wasmModule = this._injectedWasm;\n } else {\n throw new Error(\n '[Encryption] wasmModule is required. Pass the loaded openmls WASM module via options.wasmModule in initialize().',\n );\n }\n\n await this._restoreOrCreateProvider();\n }\n\n /**\n * Try to restore Provider from storage, or create a new one.\n */\n private async _restoreOrCreateProvider(): Promise<void> {\n const savedProvider = await this.storage.loadProviderState(this.userId!, this.deviceId!);\n if (savedProvider) {\n try {\n this.provider = wasmModule.Provider.from_bytes(new Uint8Array(savedProvider));\n this._providerRestored = true;\n sdkLog('info', '[Encryption] Provider restored from storage');\n return;\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to restore Provider, creating new one:', err);\n }\n }\n\n this.provider = new wasmModule.Provider();\n sdkLog('info', '[Encryption] New Provider created');\n }\n\n /**\n * Create or restore encryption identity from storage.\n */\n private async _initIdentity(): Promise<void> {\n const savedBytes = await this.storage.loadIdentity(this.userId!, this.deviceId!);\n\n if (savedBytes) {\n this.identity = wasmModule.Identity.from_bytes(this.provider, new Uint8Array(savedBytes));\n sdkLog('info', '[Encryption] Identity restored from storage');\n } else {\n this.identity = new wasmModule.Identity(this.provider, this.userId);\n const bytes = this.identity.to_bytes();\n await this.storage.saveIdentity(this.userId!, this.deviceId!, bytes);\n sdkLog('info', '[Encryption] New identity created and saved');\n }\n }\n\n /**\n * Upload N key packages to the server.\n * Called internally during init (fresh provider) or from ensureKeyPackages (health.check top-up).\n */\n private async _uploadKeyPackages(count: number): Promise<void> {\n const uploadCount = Math.max(0, Math.min(KEY_PACKAGE_POOL_TARGET, Math.floor(count)));\n if (uploadCount === 0) return;\n if (this._keyPackageUploadPromise) return this._keyPackageUploadPromise;\n\n this._keyPackageUploadPromise = (async () => {\n try {\n const kps = this.identity.key_packages(this.provider, uploadCount);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const serialized = kps.map((kp: any) => kp.to_bytes());\n await this.e2eeClient!.uploadKeyPackages({ key_packages: serialized });\n await this._persistProvider();\n sdkLog('info', `[Encryption] Uploaded ${uploadCount} key packages`);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to upload key packages:', err);\n } finally {\n this._keyPackageUploadPromise = null;\n }\n })();\n\n return this._keyPackageUploadPromise;\n }\n\n /**\n * Public method to top up key packages.\n * Called from health.check event in _handleClientEvent with the server-reported remaining count.\n * @param knownRemaining - remaining count from health.check event's me.key_packages_remaining\n */\n async ensureKeyPackages(knownRemaining: number): Promise<void> {\n if (!Number.isFinite(knownRemaining)) return;\n const remaining = Math.max(0, Math.floor(knownRemaining));\n if (remaining >= KEY_PACKAGE_POOL_TARGET) return;\n\n const toUpload = KEY_PACKAGE_POOL_TARGET - remaining;\n sdkLog(\n 'info',\n `[Encryption] Key packages below target (${remaining}/${KEY_PACKAGE_POOL_TARGET}), topping up ${toUpload}...`,\n );\n await this._uploadKeyPackages(toUpload);\n }\n\n async ensureKeyPackagesFromServer(): Promise<void> {\n try {\n const response = await this.e2eeClient!.getKeyPackageCount();\n await this.ensureKeyPackages(response.remaining);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to check key package count:', err);\n }\n }\n\n private async ensureKeyPackagesFromCachedHealthOrServer(): Promise<void> {\n const cachedRemaining = (this.client as any)?.latestKeyPackagesRemaining;\n if (typeof cachedRemaining === 'number') {\n await this.ensureKeyPackages(cachedRemaining);\n return;\n }\n\n await this.ensureKeyPackagesFromServer();\n }\n\n /**\n * Persist Provider key store to storage.\n */\n private async _persistProvider(): Promise<void> {\n try {\n const bytes = this.provider.to_bytes();\n await this.storage.saveProviderState(this.userId!, this.deviceId!, bytes);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to persist Provider:', err);\n }\n }\n\n private async _saveEncryptionSyncCheckpoint(\n options: {\n scopeCursors?: Record<string, EventCursor>;\n pendingSnapshots?: Record<string, PendingE2eeSnapshot[]>;\n repairStates?: ChannelRepairState[];\n } = {},\n ): Promise<void> {\n const providerBytes = this.provider.to_bytes();\n\n if (this.storage.saveEncryptionSyncCheckpoint) {\n await this.storage.saveEncryptionSyncCheckpoint({\n user_id: this.userId!,\n device_id: this.deviceId!,\n provider_bytes: providerBytes,\n scope_cursors: options.scopeCursors,\n pending_snapshots: options.pendingSnapshots,\n repair_states: options.repairStates,\n });\n return;\n }\n\n await this.storage.saveProviderState(this.userId!, this.deviceId!, providerBytes);\n\n if (options.scopeCursors) {\n await this._saveAllScopeSyncCursors(options.scopeCursors);\n }\n if (options.pendingSnapshots) {\n for (const [cid, snapshots] of Object.entries(options.pendingSnapshots)) {\n await this._savePendingSnapshots(cid, snapshots);\n }\n }\n if (options.repairStates) {\n for (const state of options.repairStates) {\n await this._saveChannelRepairState(state);\n }\n }\n }\n\n // ============================================================\n // PIN Epoch Archive Recovery\n // ============================================================\n\n private async _fetchVault(): Promise<RecoveryVaultResponse | null> {\n try {\n return await this.e2eeClient!.getRecoveryVault();\n } catch (err) {\n if (isVaultMissingError(err)) return null;\n throw err;\n }\n }\n\n private async _loadRecoveryPublicMetadata(): Promise<RecoveryVaultResponse | null> {\n if (this._recoveryVaultKnown === false) return null;\n if (\n this._recoveryVaultKnown === true &&\n this._recoveryVaultBytes &&\n this._recoveryPublicKey &&\n this._recoveryKeyId &&\n this._recoveryCiphersuite !== null &&\n this._recoveryVaultRevision !== null\n ) {\n return {\n vault_bytes: this._recoveryVaultBytes,\n revision: this._recoveryVaultRevision!,\n recovery_key_id: this._recoveryKeyId,\n ciphersuite: this._recoveryCiphersuite!,\n vault_format_version: 1,\n kdf_metadata: { name: 'PBKDF2-SHA256', iterations: 600_000 },\n updated_at: '',\n };\n }\n\n if (this._recoveryPublicMetadataPromise) {\n return this._recoveryPublicMetadataPromise;\n }\n\n const loadPromise = (async () => {\n const vault = await this._fetchVault();\n this._recoveryVaultKnown = vault !== null;\n this._recoveryVaultBytes = vault ? vault.vault_bytes : null;\n this._recoveryVaultRevision = vault ? vault.revision : null;\n if (!vault) return null;\n\n const wrapped = wasmModule.WrappedRecoveryKey.from_bytes(new Uint8Array(vault.vault_bytes));\n this._recoveryPublicKey = new Uint8Array(wrapped.public_key);\n this._recoveryKeyId = wrapped.key_id;\n this._recoveryCiphersuite = wrapped.ciphersuite;\n this._wrappedRecoveryKey = wrapped;\n await this.storage.saveRecoveryPublicKey(this.userId!, this._recoveryPublicKey);\n await this._flushDeferredArchives();\n return vault;\n })();\n\n this._recoveryPublicMetadataPromise = loadPromise;\n try {\n return await loadPromise;\n } finally {\n if (this._recoveryPublicMetadataPromise === loadPromise) {\n this._recoveryPublicMetadataPromise = null;\n }\n }\n }\n\n async getRecoveryStatus(): Promise<RecoveryStatus> {\n const vault = await this._loadRecoveryPublicMetadata();\n const deviceId = this.deviceId || (await this.storage.getDeviceId());\n const incompleteRecords = (await this.storage.loadIncompleteRestores(this.userId!, deviceId)).map((record) =>\n this._normalizeProgress(record),\n );\n const gapRecords = (await this.storage.loadRestoresWithPermanentGaps(this.userId!, deviceId)).map((record) =>\n this._normalizeProgress(record),\n );\n const issueRecordsByCid = new Map<string, RestoreProgressRecord>();\n for (const record of incompleteRecords) {\n if (this._isUserGatedRestoreProgress(record)) issueRecordsByCid.set(record.cid, record);\n }\n for (const record of gapRecords) issueRecordsByCid.set(record.cid, record);\n const incompleteChannels = new Set(\n incompleteRecords.filter((record) => this._isUserGatedRestoreProgress(record)).map((record) => record.cid),\n );\n\n return {\n hasVault: vault !== null,\n unlocked: this._recoveryPrivateKey !== null,\n hasIncompleteRestore: incompleteChannels.size > 0,\n incompleteChannels: Array.from(incompleteChannels),\n channelsWithPermanentGaps: gapRecords.map((record) => record.cid),\n restoreProgressWithIssues: Array.from(issueRecordsByCid.values()),\n e2eeBootstrapRunning: this._e2eeBootstrapProgress.status === 'running',\n e2eeBootstrapCompleted: this._e2eeBootstrapProgress.completed,\n e2eeBootstrapTotal: this._e2eeBootstrapProgress.total,\n };\n }\n\n clearRecoveryUnlock(): void {\n this._recoveryPrivateKey = null;\n this._wrappedRecoveryKey = null;\n this._recoveryRecheckDoneForUnlock = false;\n this._recoveryPostUnlockMaintenanceGeneration += 1;\n }\n\n private _scheduleRecoveryPostUnlockMaintenance(): void {\n if (this._recoveryPostUnlockMaintenancePromise) return;\n\n const generation = this._recoveryPostUnlockMaintenanceGeneration;\n const work = new Promise<void>((resolve) => {\n setTimeout(() => {\n if (this._recoveryPostUnlockMaintenanceGeneration !== generation || !this._recoveryPrivateKey) {\n resolve();\n return;\n }\n\n void (async () => {\n try {\n await this._flushDeferredArchives();\n } catch (err) {\n sdkLog('warn', '[Encryption] Recovery post-unlock deferred archive flush failed:', err);\n }\n\n try {\n await this._resumeEpochArchiveCheckpoints();\n } catch (err) {\n sdkLog('warn', '[Encryption] Recovery post-unlock archive checkpoint resume failed:', err);\n }\n\n try {\n await this._recheckKnownRecoveryChannelsOnce();\n } catch (err) {\n sdkLog('warn', '[Encryption] Recovery post-unlock channel recheck failed:', err);\n }\n })().finally(resolve);\n }, 0);\n });\n\n this._recoveryPostUnlockMaintenancePromise = work;\n void work.finally(() => {\n if (this._recoveryPostUnlockMaintenancePromise === work) {\n this._recoveryPostUnlockMaintenancePromise = null;\n }\n });\n }\n\n async setupRecoveryPin(pin: string): Promise<void> {\n if (!/^\\d{8,}$/.test(pin)) {\n throw new Error('PIN must be at least 8 digits');\n }\n const keypair = wasmModule.generate_recovery_keypair(this.provider);\n const wrapped = wasmModule.wrap_recovery_private_key(\n this.provider,\n pin,\n keypair.private_key,\n keypair.public_key,\n keypair.key_id,\n keypair.ciphersuite,\n 600_000,\n );\n const vaultBytes = wrapped.to_bytes();\n const write = await this.e2eeClient!.uploadRecoveryVault({ vault_bytes: vaultBytes });\n if (write.status === 'conflict') {\n throw new Error('A recovery vault already exists. Reload it before setting a PIN.');\n }\n this._recoveryVaultKnown = true;\n this._recoveryVaultBytes = vaultBytes;\n this._recoveryVaultRevision = write.revision;\n this._recoveryPublicMetadataPromise = null;\n this._recoveryPrivateKey = new Uint8Array(keypair.private_key);\n this._recoveryPublicKey = new Uint8Array(keypair.public_key);\n this._recoveryKeyId = keypair.key_id;\n this._recoveryCiphersuite = keypair.ciphersuite;\n this._wrappedRecoveryKey = wrapped;\n await this.storage.saveRecoveryPublicKey(this.userId!, this._recoveryPublicKey);\n this._scheduleRecoveryPostUnlockMaintenance();\n }\n\n async unlockRecoveryVault(pin: string): Promise<void> {\n const vault = await this._loadRecoveryPublicMetadata();\n if (!vault) throw new Error('Recovery vault not found.');\n const wrapped =\n this._wrappedRecoveryKey || wasmModule.WrappedRecoveryKey.from_bytes(new Uint8Array(vault.vault_bytes));\n const privateKey = wasmModule.unwrap_recovery_private_key(this.provider, pin, wrapped);\n this._recoveryVaultKnown = true;\n this._recoveryVaultBytes = vault.vault_bytes;\n this._recoveryVaultRevision = vault.revision;\n this._recoveryPrivateKey = new Uint8Array(privateKey);\n this._recoveryPublicKey = new Uint8Array(wrapped.public_key);\n this._recoveryKeyId = wrapped.key_id;\n this._recoveryCiphersuite = wrapped.ciphersuite;\n this._wrappedRecoveryKey = wrapped;\n await this.storage.saveRecoveryPublicKey(this.userId!, this._recoveryPublicKey);\n this._scheduleRecoveryPostUnlockMaintenance();\n }\n\n async changeRecoveryPin(oldPin: string, newPin: string): Promise<void> {\n if (!/^\\d{8,}$/.test(newPin)) {\n throw new Error('PIN must be at least 8 digits');\n }\n if (!this._wrappedRecoveryKey || !this._recoveryPublicKey || !this._recoveryKeyId || !this._recoveryCiphersuite) {\n await this.unlockRecoveryVault(oldPin);\n }\n const privateKey = wasmModule.unwrap_recovery_private_key(this.provider, oldPin, this._wrappedRecoveryKey);\n const newWrapped = wasmModule.wrap_recovery_private_key(\n this.provider,\n newPin,\n privateKey,\n this._recoveryPublicKey,\n this._recoveryKeyId,\n this._recoveryCiphersuite,\n 600_000,\n );\n if (this._recoveryVaultRevision === null) {\n throw new Error('Recovery vault revision is unavailable. Reload the vault before changing the PIN.');\n }\n const write = await this.e2eeClient!.uploadRecoveryVault({\n vault_bytes: newWrapped.to_bytes(),\n expected_revision: this._recoveryVaultRevision,\n });\n if (write.status === 'conflict') {\n throw new Error('Recovery PIN changed on another device. Reload the vault and try again.');\n }\n this._recoveryVaultRevision = write.revision;\n this._wrappedRecoveryKey = newWrapped;\n this._recoveryPrivateKey = new Uint8Array(privateKey);\n this._recoveryVaultBytes = newWrapped.to_bytes();\n }\n\n async changeUnlockedRecoveryPin(newPin: string): Promise<void> {\n if (!/^\\d{8,}$/.test(newPin)) {\n throw new Error('PIN must be at least 8 digits');\n }\n if (!this._recoveryPrivateKey || !this._recoveryPublicKey || !this._recoveryKeyId || !this._recoveryCiphersuite) {\n throw new Error('Recovery vault must be unlocked before changing the PIN.');\n }\n const newWrapped = wasmModule.wrap_recovery_private_key(\n this.provider,\n newPin,\n this._recoveryPrivateKey,\n this._recoveryPublicKey,\n this._recoveryKeyId,\n this._recoveryCiphersuite,\n 600_000,\n );\n const vaultBytes = newWrapped.to_bytes();\n if (this._recoveryVaultRevision === null) {\n throw new Error('Recovery vault revision is unavailable. Reload the vault before changing the PIN.');\n }\n const write = await this.e2eeClient!.uploadRecoveryVault({\n vault_bytes: vaultBytes,\n expected_revision: this._recoveryVaultRevision,\n });\n if (write.status === 'conflict') {\n throw new Error('Recovery PIN changed on another device. Reload the vault and try again.');\n }\n this._recoveryVaultRevision = write.revision;\n this._wrappedRecoveryKey = newWrapped;\n this._recoveryVaultBytes = vaultBytes;\n this._recoveryVaultKnown = true;\n }\n\n hasRecoveryKey(): boolean {\n return !!this._recoveryPublicKey || !!this._wrappedRecoveryKey;\n }\n\n isRecoveryVaultUnlocked(): boolean {\n return this._recoveryPrivateKey !== null;\n }\n\n async archiveCurrentEpoch(\n channelType: string,\n channelId: string,\n sponsorRole: EpochArchiveCheckpoint['sponsor_role'] = 'primary',\n primaryUserId?: string,\n ): Promise<void> {\n const cid = cidFromParts(channelType, channelId);\n const group = this.groups.get(cid);\n if (!group) return;\n const epochBigInt = toEpochBigInt(group.epoch());\n const epoch = Number(epochBigInt);\n const existing = await this.storage.loadEpochArchiveCheckpoint(cid, epoch);\n if (existing) {\n void this._materializeEpochArchiveCheckpoint(existing);\n return;\n }\n\n const exported = group.archive_epoch_v2();\n const snapshotHash = bytesToHex(exported.snapshot_hash);\n const now = Date.now();\n const checkpoint: EpochArchiveCheckpoint = {\n scope_cid: cid,\n channel_type: channelType,\n channel_id: channelId,\n epoch,\n encrypted_archive_bytes: await this._encryptArchiveStashBytes(new Uint8Array(exported.archive_bytes)),\n snapshot: {\n snapshot_bytes: new Uint8Array(exported.snapshot_bytes),\n snapshot_hash: snapshotHash,\n },\n sponsor_role: sponsorRole,\n primary_user_id: primaryUserId || (sponsorRole === 'primary' ? this.userId || undefined : undefined),\n materialization: {\n account_owned: 'pending',\n group_sponsored: this._sponsoredArchiveDisabled ? 'unsupported' : 'pending',\n },\n captured_at: now,\n updated_at: now,\n };\n await this.storage.saveEpochArchiveCheckpoint(checkpoint);\n void this._materializeEpochArchiveCheckpoint(checkpoint);\n }\n\n private async _materializeArchiveUpload(\n checkpoint: EpochArchiveCheckpoint,\n scope: ArchiveScope,\n recipients: Array<{ user_id: string; recovery_key_id: string; public_key: Uint8Array }>,\n recipientSetHash?: string,\n ): Promise<UploadEpochArchiveRequest> {\n const archiveBytes = await this._decryptArchiveStashBytes(checkpoint.encrypted_archive_bytes);\n const epochBigInt = BigInt(checkpoint.epoch);\n const archiveBlobId = newArchiveBlobId();\n const aad = new wasmModule.ArchiveBlobAad(\n checkpoint.scope_cid,\n epochBigInt,\n scope,\n archiveBlobId,\n checkpoint.snapshot.snapshot_hash,\n );\n const encrypted = wasmModule.encrypt_archive_blob(this.provider, archiveBytes, aad);\n const wraps = recipients.map((recipient) => {\n const info = new wasmModule.ArchiveKeyWrapInfo(\n checkpoint.scope_cid,\n epochBigInt,\n scope,\n archiveBlobId,\n checkpoint.snapshot.snapshot_hash,\n recipient.recovery_key_id,\n );\n const wrapped = wasmModule.wrap_archive_data_key(\n this.provider,\n new Uint8Array(encrypted.adk),\n recipient.public_key,\n info,\n );\n return {\n recipient_user_id: recipient.user_id,\n recipient_recovery_key_id: recipient.recovery_key_id,\n hpke_kem_output: wrapped.kem_output,\n hpke_ciphertext: wrapped.ciphertext,\n ciphersuite: wrapped.ciphersuite,\n hpke_info: wrapped.hpke_info,\n };\n });\n return {\n epoch: checkpoint.epoch,\n archive_blob_id: archiveBlobId,\n idempotency_key: `${checkpoint.epoch}:${scope}:${this.deviceId || 'web'}:${archiveBlobId}`,\n scope,\n ...(recipientSetHash ? { recipient_set_hash: recipientSetHash } : {}),\n encrypted_archive: {\n ciphertext: encrypted.ciphertext,\n nonce: encrypted.nonce,\n aead_aad: encrypted.aead_aad,\n },\n snapshot: checkpoint.snapshot,\n wraps,\n };\n }\n\n private async _saveCheckpointMaterialization(\n checkpoint: EpochArchiveCheckpoint,\n scope: ArchiveScope,\n status: EpochArchiveCheckpoint['materialization'][ArchiveScope],\n error?: string,\n ): Promise<EpochArchiveCheckpoint> {\n const next: EpochArchiveCheckpoint = {\n ...checkpoint,\n materialization: { ...checkpoint.materialization, [scope]: status },\n last_error: error,\n updated_at: Date.now(),\n };\n await this.storage.saveEpochArchiveCheckpoint(next);\n const completed = Object.values(next.materialization).every(\n (value) => value === 'uploaded' || value === 'terminal' || value === 'unsupported',\n );\n if (completed) await this.storage.deleteEpochArchiveCheckpoint(next.scope_cid, next.epoch);\n return next;\n }\n\n private _materializeEpochArchiveCheckpoint(checkpoint: EpochArchiveCheckpoint): Promise<void> {\n const key = `${checkpoint.scope_cid}:${checkpoint.epoch}`;\n const existing = this._archiveCheckpointMaterializations.get(key);\n if (existing) return existing;\n const job = this._runEpochArchiveCheckpointMaterialization(checkpoint).finally(() => {\n if (this._archiveCheckpointMaterializations.get(key) === job) {\n this._archiveCheckpointMaterializations.delete(key);\n }\n });\n this._archiveCheckpointMaterializations.set(key, job);\n return job;\n }\n\n private async _runEpochArchiveCheckpointMaterialization(checkpoint: EpochArchiveCheckpoint): Promise<void> {\n let current = checkpoint;\n try {\n if (\n current.materialization.account_owned === 'pending' &&\n this._recoveryPublicKey &&\n this._recoveryKeyId &&\n !(await this._hasArchiveAcknowledged(current.scope_cid, current.epoch, 'account_owned', this._recoveryKeyId)) &&\n !(await this._hasPendingArchiveWork(current.scope_cid, current.epoch, 'account_owned'))\n ) {\n const upload = await this._materializeArchiveUpload(current, 'account_owned', [\n { user_id: this.userId!, recovery_key_id: this._recoveryKeyId, public_key: this._recoveryPublicKey },\n ]);\n await this._enqueueArchiveUpload({\n cid: current.scope_cid,\n channel_type: current.channel_type,\n channel_id: current.channel_id,\n epoch: current.epoch,\n scope: 'account_owned',\n upload,\n retry_count: 0,\n created_at: Date.now(),\n });\n }\n } catch (err) {\n current = await this._saveCheckpointMaterialization(current, 'account_owned', 'pending', getApiErrorMessage(err));\n }\n\n if (current.materialization.group_sponsored === 'pending' && !this._sponsoredArchiveDisabled) {\n try {\n if (current.sponsor_role === 'backup') {\n await new Promise((resolve) => setTimeout(resolve, 5_000));\n if (!this._isDesignatedArchiveBackup(current.scope_cid, current.primary_user_id)) {\n await this._saveCheckpointMaterialization(current, 'group_sponsored', 'unsupported');\n await this._drainArchiveUploadQueue();\n return;\n }\n }\n const recipients = await this.e2eeClient!.querySponsoredArchiveRecipients(\n current.channel_type,\n current.channel_id,\n current.epoch,\n );\n if (recipients.matching_candidate_exists) {\n current = await this._saveCheckpointMaterialization(current, 'group_sponsored', 'uploaded');\n } else if (!recipients.recipient_set_hash || recipients.recipients.length === 0 || recipients.reason) {\n current = await this._saveCheckpointMaterialization(\n current,\n 'group_sponsored',\n 'terminal',\n recipients.reason,\n );\n } else if (\n !(await this._hasArchiveAcknowledged(\n current.scope_cid,\n current.epoch,\n 'group_sponsored',\n recipients.recipient_set_hash,\n )) &&\n !(await this._hasPendingArchiveWork(current.scope_cid, current.epoch, 'group_sponsored'))\n ) {\n const upload = await this._materializeArchiveUpload(\n current,\n 'group_sponsored',\n recipients.recipients,\n recipients.recipient_set_hash,\n );\n await this._enqueueArchiveUpload({\n cid: current.scope_cid,\n channel_type: current.channel_type,\n channel_id: current.channel_id,\n epoch: current.epoch,\n scope: 'group_sponsored',\n upload,\n retry_count: 0,\n created_at: Date.now(),\n });\n }\n } catch (err) {\n const status = Number((err as any)?.response?.status ?? (err as any)?.status);\n const unsupported =\n status === 404 ||\n status === 405 ||\n getApiErrorMessage(err).includes('account_owned') ||\n getApiErrorMessage(err).includes('unsupported scope');\n if (unsupported) {\n this._sponsoredArchiveDisabled = true;\n current = await this._saveCheckpointMaterialization(current, 'group_sponsored', 'unsupported');\n } else {\n current = await this._saveCheckpointMaterialization(\n current,\n 'group_sponsored',\n 'pending',\n getApiErrorMessage(err),\n );\n }\n }\n }\n void current;\n await this._drainArchiveUploadQueue();\n }\n\n private _isDesignatedArchiveBackup(scopeCid: string, primaryUserId?: string): boolean {\n const group = this.groups.get(scopeCid);\n const channel = this._getActiveChannel(scopeCid);\n if (!group || !channel || !this.userId) return false;\n const candidates: Array<{ userId: string; leafIndex: number }> = [];\n for (const userId of Object.keys(channel.state?.members || {})) {\n try {\n for (const member of group.members_by_user_id(userId) || []) {\n candidates.push({ userId, leafIndex: Number(member.index) });\n }\n } catch (_) {\n // Membership state can be transient while a commit is being persisted.\n }\n }\n candidates.sort((left, right) => left.userId.localeCompare(right.userId) || left.leafIndex - right.leafIndex);\n const selected = candidates.find((candidate) => candidate.userId !== primaryUserId);\n return !!selected && selected.userId === this.userId && selected.leafIndex === Number(group.own_leaf_index());\n }\n\n private async _resumeEpochArchiveCheckpoints(): Promise<void> {\n const checkpoints = await this.storage.loadEpochArchiveCheckpoints().catch(() => []);\n for (const checkpoint of checkpoints) {\n void this._materializeEpochArchiveCheckpoint(checkpoint);\n }\n }\n\n private async _hasArchiveAcknowledged(\n cid: string,\n epoch: number,\n scope: ArchiveScope = 'account_owned',\n coverageKey?: string,\n ): Promise<boolean> {\n const key = coverageKey || (scope === 'account_owned' ? this._recoveryKeyId : null);\n if (!key) return false;\n return !!(await this.storage.loadArchiveAck(cid, epoch, scope, key));\n }\n\n private async _hasPendingArchiveWork(cid: string, epoch: number, scope: ArchiveScope): Promise<boolean> {\n const [uploads, deferred] = await Promise.all([\n this.storage.loadPendingArchiveUploads(),\n this.storage.loadPendingDeferredArchives(),\n ]);\n return (\n uploads.some((item) => item.cid === cid && item.epoch === epoch && item.scope === scope) ||\n (scope === 'account_owned' && deferred.some((item) => item.cid === cid && item.epoch === epoch))\n );\n }\n\n private _getBrowserCrypto(): Crypto {\n const cryptoImpl = globalThis.crypto;\n if (!cryptoImpl?.subtle || !cryptoImpl.getRandomValues) {\n throw new Error('WebCrypto is required to protect deferred archive material.');\n }\n return cryptoImpl;\n }\n\n private async _getArchiveStashKey(): Promise<CryptoKey> {\n if (this._archiveStashKey) return this._archiveStashKey;\n if (this._archiveStashKeyPromise) return this._archiveStashKeyPromise;\n\n this._archiveStashKeyPromise = (async () => {\n const existing = await this.storage.loadArchiveStashKey();\n if (existing) {\n this._archiveStashKey = existing;\n return existing;\n }\n const key = await this._getBrowserCrypto().subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, [\n 'encrypt',\n 'decrypt',\n ]);\n await this.storage.saveArchiveStashKey(key);\n this._archiveStashKey = key;\n return key;\n })();\n\n try {\n return await this._archiveStashKeyPromise;\n } finally {\n this._archiveStashKeyPromise = null;\n }\n }\n\n private async _encryptArchiveStashBytes(bytes: Uint8Array): Promise<{ ciphertext: Uint8Array; nonce: Uint8Array }> {\n const cryptoImpl = this._getBrowserCrypto();\n const key = await this._getArchiveStashKey();\n const nonce = new Uint8Array(12);\n cryptoImpl.getRandomValues(nonce);\n const plaintext = new Uint8Array(bytes.length);\n plaintext.set(bytes);\n const ciphertext = await cryptoImpl.subtle.encrypt({ name: 'AES-GCM', iv: nonce }, key, plaintext.buffer);\n return { ciphertext: new Uint8Array(ciphertext), nonce };\n }\n\n private async _decryptArchiveStashBytes(encrypted: {\n ciphertext: Uint8Array;\n nonce: Uint8Array;\n }): Promise<Uint8Array> {\n const key = await this._getArchiveStashKey();\n const nonce = new Uint8Array(encrypted.nonce);\n const ciphertext = new Uint8Array(encrypted.ciphertext);\n const plaintext = await this._getBrowserCrypto().subtle.decrypt({ name: 'AES-GCM', iv: nonce }, key, ciphertext);\n return new Uint8Array(plaintext);\n }\n\n private _listKnownE2eeChannels(): Array<{ cid: string; channelType: string; channelId: string }> {\n const activeChannels = (this.client as any)?.activeChannels as Record<string, any> | undefined;\n if (!activeChannels) return [];\n const seen = new Set<string>();\n const channels: Array<{ cid: string; channelType: string; channelId: string }> = [];\n for (const [cid, channel] of Object.entries(activeChannels)) {\n if (!channel?.id || !this._isE2eeChannelData(channel.data || channel) || seen.has(cid)) continue;\n if (this._isInactiveInviteRole(this._membershipRoleForChannel(channel))) continue;\n if (this._resolveChannelE2eeGroupId(cid, channel) !== cid) continue;\n seen.add(cid);\n channels.push({ cid, channelType: channel.type, channelId: channel.id });\n }\n return channels;\n }\n\n private _isRecentMembership(channel: any): boolean {\n const createdAt = this._getMembershipCreatedAt(channel);\n if (!createdAt) return false;\n const createdAtMs = Date.parse(createdAt);\n return Number.isFinite(createdAtMs) && Date.now() - createdAtMs < RECENT_INVITE_ACCEPT_RESTORE_PROMPT_GRACE_MS;\n }\n\n private async _markKnownChannelPendingRecoveryUnlock(channel: {\n cid: string;\n channelType: string;\n channelId: string;\n }): Promise<void> {\n if (!this.userId || !this.deviceId || !this.storage || this._recoveryPrivateKey) return;\n const vault = await this._loadRecoveryPublicMetadata().catch(() => null);\n if (!vault) return;\n\n const activeChannel = this._getActiveChannel(channel.cid);\n if (this._isRecentMembership(activeChannel)) return;\n\n const existing = await this.storage.loadRestoreProgress(this.userId, this.deviceId, channel.cid);\n const progress = existing\n ? this._normalizeProgress(existing)\n : this._newRestoreProgressRecord(channel.channelType, channel.channelId);\n if (progress.status === 'done' || progress.status === 'done_with_gaps') return;\n if (this._isUserGatedRestoreProgress(progress)) return;\n\n await this._saveRestoreProgress(\n {\n ...progress,\n requires_user_action: 'unlock_recovery_vault',\n },\n 'pending',\n );\n }\n\n private async _markKnownChannelsPendingRecoveryUnlock(\n channels: Array<{ cid: string; channelType: string; channelId: string }>,\n ): Promise<void> {\n if (this._recoveryPrivateKey) return;\n for (const channel of channels) {\n if (!this.groups.has(channel.cid)) continue;\n await this._markKnownChannelPendingRecoveryUnlock(channel);\n }\n }\n\n private _emitBootstrapProgress(progress: E2eeBootstrapProgress): void {\n this._e2eeBootstrapProgress = { ...progress, failed_cids: [...progress.failed_cids] };\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.bootstrap_progress',\n ...this._e2eeBootstrapProgress,\n } as any);\n }\n\n private _registerKnownChannelBootstrapListener(): void {\n if (this._channelBootstrapSub || !(this.client as any)?.on) return;\n this._channelBootstrapSub = (this.client as any).on('channels.queried', () => {\n void this.bootstrapKnownE2eeChannels({ source: 'channels_queried' });\n });\n }\n\n async bootstrapKnownE2eeChannels(\n options: BootstrapKnownE2eeChannelsOptions = {},\n ): Promise<BootstrapKnownE2eeChannelsResult> {\n if (!this.initialized) {\n return { ...this._e2eeBootstrapProgress, results: [] };\n }\n if (this._bootstrapKnownChannelsPromise) {\n return this._bootstrapKnownChannelsPromise;\n }\n\n const work = (async (): Promise<BootstrapKnownE2eeChannelsResult> => {\n const knownChannels = this._listKnownE2eeChannels();\n let channels = knownChannels.filter((channel) => !this.groups.has(channel.cid));\n if (options.priorityActiveCid) {\n channels = [\n ...channels.filter((channel) => channel.cid === options.priorityActiveCid),\n ...channels.filter((channel) => channel.cid !== options.priorityActiveCid),\n ];\n }\n\n const failedCids: string[] = [];\n const results: EnsureE2eeChannelResult[] = [];\n this._emitBootstrapProgress({\n total: channels.length,\n completed: 0,\n failed_cids: failedCids,\n status: channels.length > 0 ? 'running' : 'done',\n });\n\n let completed = 0;\n for (const channel of channels) {\n this._emitBootstrapProgress({\n total: channels.length,\n completed,\n running_cid: channel.cid,\n failed_cids: failedCids,\n status: 'running',\n });\n\n try {\n const result = await this.ensureChannelReady(channel.channelType, channel.channelId, channel.cid, {\n source: options.source || 'startup',\n });\n results.push(result);\n if (result.status === 'failed' || result.status === 'stale_group_info') {\n failedCids.push(channel.cid);\n } else if (this.groups.has(channel.cid)) {\n if (this._recoveryPrivateKey) {\n this.enqueueRestore(channel.channelType, channel.channelId, 'background');\n } else {\n await this._markKnownChannelPendingRecoveryUnlock(channel);\n }\n }\n } catch (err) {\n failedCids.push(channel.cid);\n results.push({\n cid: channel.cid,\n status: 'failed',\n error: err instanceof Error ? err.message : String(err),\n });\n sdkLog('warn', '[Encryption] Known E2EE channel bootstrap failed:', channel.cid, err);\n } finally {\n completed += 1;\n this._emitBootstrapProgress({\n total: channels.length,\n completed,\n failed_cids: failedCids,\n status: failedCids.length > 0 && completed === channels.length ? 'failed' : 'running',\n });\n }\n }\n\n const finalStatus: E2eeBootstrapStatus = failedCids.length > 0 ? 'failed' : 'done';\n const finalProgress: E2eeBootstrapProgress = {\n total: channels.length,\n completed,\n failed_cids: failedCids,\n status: finalStatus,\n };\n this._emitBootstrapProgress(finalProgress);\n if (this._recoveryPrivateKey) {\n for (const channel of knownChannels) {\n if (this.groups.has(channel.cid)) {\n this.enqueueRestore(channel.channelType, channel.channelId, 'background');\n }\n }\n } else {\n await this._markKnownChannelsPendingRecoveryUnlock(knownChannels);\n }\n return { ...finalProgress, results };\n })().finally(() => {\n this._bootstrapKnownChannelsPromise = null;\n });\n\n this._bootstrapKnownChannelsPromise = work;\n return work;\n }\n\n private _listKnownE2eeTimelines(): Array<{ cid: string; channelType: string; channelId: string }> {\n const activeChannels = (this.client as any)?.activeChannels as Record<string, any> | undefined;\n if (!activeChannels) return [];\n const seen = new Set<string>();\n const timelines: Array<{ cid: string; channelType: string; channelId: string }> = [];\n for (const [cid, channel] of Object.entries(activeChannels)) {\n if (!channel?.id || !this._isE2eeChannelData(channel.data || channel) || seen.has(cid)) continue;\n if (this._isInactiveInviteRole(this._membershipRoleForChannel(channel))) continue;\n seen.add(cid);\n timelines.push({ cid, channelType: channel.type, channelId: channel.id });\n }\n return timelines;\n }\n\n private async _recheckKnownRecoveryChannelsOnce(): Promise<void> {\n if (!this._recoveryPrivateKey || this._recoveryRecheckDoneForUnlock) return;\n this._recoveryRecheckDoneForUnlock = true;\n\n await this.bootstrapKnownE2eeChannels({ source: 'recovery_unlock' }).catch((err) => {\n sdkLog('warn', '[Encryption] Recovery unlock bootstrap did not fully complete; continuing archive recheck:', err);\n });\n\n for (const timeline of this._listKnownE2eeTimelines()) {\n try {\n await this.repairRecoveryChannel(timeline.channelType, timeline.channelId, { mode: 'recheck_channel' });\n } catch (err) {\n sdkLog('warn', '[Encryption] Recovery unlock archive recheck failed:', timeline.cid, err);\n }\n }\n }\n\n private async archiveCurrentEpochForCid(\n cid: string,\n sponsorRole: EpochArchiveCheckpoint['sponsor_role'] = 'primary',\n primaryUserId?: string,\n ): Promise<void> {\n const parts = channelPartsFromCid(cid);\n if (!parts) return;\n await this.archiveCurrentEpoch(parts.channelType, parts.channelId, sponsorRole, primaryUserId);\n }\n\n private async safeArchiveCurrentEpoch(\n channelType: string,\n channelId: string,\n sponsorRole: EpochArchiveCheckpoint['sponsor_role'] = 'primary',\n primaryUserId?: string,\n ): Promise<void> {\n try {\n await this.archiveCurrentEpoch(channelType, channelId, sponsorRole, primaryUserId);\n } catch (err) {\n sdkLog(\n 'warn',\n '[Encryption] Archive current epoch failed; continuing encryption flow:',\n channelType,\n channelId,\n err,\n );\n }\n }\n\n private async safeArchiveCurrentEpochForCid(\n cid: string,\n sponsorRole: EpochArchiveCheckpoint['sponsor_role'] = 'primary',\n primaryUserId?: string,\n ): Promise<void> {\n const parts = channelPartsFromCid(cid);\n if (!parts) return;\n await this.safeArchiveCurrentEpoch(parts.channelType, parts.channelId, sponsorRole, primaryUserId);\n }\n\n private async _enqueueArchiveUpload(upload: PendingArchiveUpload): Promise<void> {\n await this.storage.saveArchiveUpload(upload);\n }\n\n private async _flushDeferredArchives(): Promise<void> {\n if (!this._recoveryPublicKey || !this._recoveryKeyId) return;\n const deferred = await this.storage.loadPendingDeferredArchives();\n for (const record of deferred) {\n try {\n if (await this._hasArchiveAcknowledged(record.cid, record.epoch)) {\n await this.storage.deleteDeferredArchive(record.cid, record.epoch, record.archive_blob_id);\n continue;\n }\n\n const pendingUploads = await this.storage.loadPendingArchiveUploads();\n const alreadyQueued = pendingUploads.some(\n (item) =>\n item.cid === record.cid &&\n item.epoch === record.epoch &&\n item.scope === 'account_owned' &&\n (item.upload as UploadEpochArchiveRequest)?.archive_blob_id === record.archive_blob_id,\n );\n if (alreadyQueued) {\n await this.storage.deleteDeferredArchive(record.cid, record.epoch, record.archive_blob_id);\n continue;\n }\n\n const adk = await this._decryptArchiveStashBytes(record.encrypted_adk);\n await this._enqueueArchiveUploadFromDeferred(record, adk);\n await this.storage.deleteDeferredArchive(record.cid, record.epoch, record.archive_blob_id);\n } catch (err) {\n await this.storage.saveDeferredArchive({\n ...record,\n retry_count: record.retry_count + 1,\n updated_at: Date.now(),\n });\n sdkLog('warn', '[Encryption] Deferred archive flush failed; keeping for retry:', record.cid, record.epoch, err);\n }\n }\n await this._drainArchiveUploadQueue();\n }\n\n private async _enqueueArchiveUploadFromDeferred(record: PendingDeferredArchive, adk: Uint8Array): Promise<void> {\n if (!this._recoveryPublicKey || !this._recoveryKeyId) {\n throw new Error('Recovery public key is not available.');\n }\n const epochBigInt = BigInt(record.epoch);\n const info = new wasmModule.ArchiveKeyWrapInfo(\n record.cid,\n epochBigInt,\n record.scope,\n record.archive_blob_id,\n record.snapshot.snapshot_hash,\n this._recoveryKeyId,\n );\n const wrappedAdk = wasmModule.wrap_archive_data_key(this.provider, adk, this._recoveryPublicKey, info);\n const upload: UploadEpochArchiveRequest = {\n epoch: record.epoch,\n archive_blob_id: record.archive_blob_id,\n idempotency_key: `${record.epoch}:account_owned:${this.deviceId || 'web'}:${record.archive_blob_id}`,\n scope: record.scope,\n encrypted_archive: record.encrypted_archive,\n snapshot: record.snapshot,\n wraps: [\n {\n recipient_user_id: this.userId!,\n recipient_recovery_key_id: this._recoveryKeyId,\n hpke_kem_output: wrappedAdk.kem_output,\n hpke_ciphertext: wrappedAdk.ciphertext,\n ciphersuite: wrappedAdk.ciphersuite,\n hpke_info: wrappedAdk.hpke_info,\n },\n ],\n };\n await this._enqueueArchiveUpload({\n cid: record.cid,\n channel_type: record.channel_type,\n channel_id: record.channel_id,\n epoch: record.epoch,\n scope: record.scope,\n upload,\n retry_count: record.retry_count,\n created_at: record.created_at,\n });\n }\n\n private async _markArchiveUploadAcknowledged(\n item: PendingArchiveUpload,\n upload: UploadEpochArchiveRequest,\n reason?: string,\n ): Promise<void> {\n const coverageKey =\n upload.scope === 'group_sponsored' ? upload.recipient_set_hash : upload.wraps?.[0]?.recipient_recovery_key_id;\n if (!coverageKey) return;\n const status = reason === 'duplicate_cap' ? 'duplicate_cap' : reason === 'idempotent' ? 'idempotent' : 'uploaded';\n await this.storage.saveArchiveAck({\n cid: item.cid,\n epoch: item.epoch,\n scope: upload.scope,\n coverage_key: coverageKey,\n ...(upload.scope === 'account_owned' ? { recovery_key_id: coverageKey } : { recipient_set_hash: coverageKey }),\n status,\n archive_blob_id: upload.archive_blob_id,\n updated_at: Date.now(),\n });\n const checkpoint = await this.storage.loadEpochArchiveCheckpoint(item.cid, item.epoch);\n if (checkpoint) {\n await this._saveCheckpointMaterialization(checkpoint, upload.scope, 'uploaded');\n }\n }\n\n private async _drainArchiveUploadQueue(): Promise<void> {\n const pending = await this.storage.loadPendingArchiveUploads();\n for (const item of pending) {\n const upload = item.upload as UploadEpochArchiveRequest;\n try {\n const response = await this.e2eeClient!.uploadEpochArchive(item.channel_type, item.channel_id, upload);\n await this.storage.deleteArchiveUpload(item.cid, item.epoch, upload.archive_blob_id);\n if (response.reason_code === 'recipient_set_stale' && upload.scope === 'group_sponsored') {\n const checkpoint = await this.storage.loadEpochArchiveCheckpoint(item.cid, item.epoch);\n if (checkpoint && (checkpoint.sponsored_rewrap_count || 0) < 2) {\n const next = {\n ...checkpoint,\n sponsored_rewrap_count: (checkpoint.sponsored_rewrap_count || 0) + 1,\n updated_at: Date.now(),\n };\n await this.storage.saveEpochArchiveCheckpoint(next);\n await this._saveCheckpointMaterialization(next, 'group_sponsored', 'pending', response.reason_code);\n void this._materializeEpochArchiveCheckpoint(next);\n } else if (checkpoint) {\n await this._saveCheckpointMaterialization(checkpoint, 'group_sponsored', 'terminal', response.reason_code);\n }\n continue;\n }\n await this._markArchiveUploadAcknowledged(item, upload, response.reason_code);\n if (response.status !== 'stored') {\n sdkLog(\n 'info',\n '[Encryption] Archive upload acknowledged without storing:',\n item.cid,\n item.epoch,\n response.reason_code,\n );\n }\n } catch (err) {\n const ermisCode = getApiErrorCode(err);\n if (!isRetryableRecoveryNetworkError(err)) {\n await this.storage.deleteArchiveUpload(item.cid, item.epoch, upload.archive_blob_id);\n const checkpoint = await this.storage.loadEpochArchiveCheckpoint(item.cid, item.epoch);\n if (checkpoint) {\n const unsupportedSponsored =\n upload.scope === 'group_sponsored' &&\n (getApiErrorMessage(err).includes('account_owned') ||\n getApiErrorMessage(err).includes('unsupported scope') ||\n Number((err as any)?.response?.status ?? (err as any)?.status) === 404 ||\n Number((err as any)?.response?.status ?? (err as any)?.status) === 405);\n if (unsupportedSponsored) this._sponsoredArchiveDisabled = true;\n await this._saveCheckpointMaterialization(\n checkpoint,\n upload.scope,\n unsupportedSponsored ? 'unsupported' : 'terminal',\n getApiErrorMessage(err),\n );\n }\n sdkLog('warn', '[Encryption] Archive upload rejected; removing non-retryable work item:', {\n cid: item.cid,\n epoch: item.epoch,\n ermisCode,\n error: getApiErrorMessage(err),\n });\n continue;\n }\n item.retry_count += 1;\n await this.storage.saveArchiveUpload(item);\n sdkLog('warn', '[Encryption] Archive upload failed, queued for retry:', item.cid, item.epoch, err);\n }\n }\n }\n\n private _newRestoreProgressRecord(channelType: string, channelId: string): RestoreProgressRecord {\n const now = Date.now();\n return {\n device_id: this.deviceId!,\n cid: cidFromParts(channelType, channelId),\n user_id: this.userId!,\n channel_type: channelType,\n channel_id: channelId,\n status: 'pending',\n completed_epochs: [],\n permanent_gaps: [],\n transient_failures: [],\n repair_issues: [],\n last_checked_at: now,\n updated_at: now,\n };\n }\n\n private _normalizeProgress(record: RestoreProgressRecord): RestoreProgressRecord {\n const completed = Array.from(new Set(record.completed_epochs || [])).sort((a, b) => a - b);\n const permanentByEpoch = new Map<number, RestoreProgressRecord['permanent_gaps'][number]>();\n for (const gap of record.permanent_gaps || []) permanentByEpoch.set(gap.epoch, gap);\n const transientByEpoch = new Map<number, RestoreProgressRecord['transient_failures'][number]>();\n for (const failure of record.transient_failures || []) {\n if (!permanentByEpoch.has(failure.epoch)) transientByEpoch.set(failure.epoch, failure);\n }\n const repairByVersion = new Map<string, RepairIssue>();\n for (const issue of record.repair_issues || []) {\n const messageVersion = issue.message_id.startsWith('legacy-epoch-')\n ? issue.message_version\n : this._messageVersionKey({\n id: issue.message_id,\n created_at: issue.created_at,\n updated_at:\n typeof issue.encrypted_message?.updated_at === 'string' ? issue.encrypted_message.updated_at : undefined,\n });\n const existing = repairByVersion.get(messageVersion);\n const latest = existing && existing.updated_at > issue.updated_at ? existing : issue;\n repairByVersion.set(messageVersion, { ...latest, message_version: messageVersion });\n }\n if (record.repair_issues === undefined) {\n for (const gap of permanentByEpoch.values()) {\n const messageVersion = `legacy-epoch:${gap.epoch}:${gap.reason}`;\n repairByVersion.set(messageVersion, {\n cid: record.cid,\n message_id: `legacy-epoch-${gap.epoch}`,\n message_version: messageVersion,\n mls_epoch: gap.epoch,\n reason: gap.reason,\n status: gap.reason === 'expired_restore_window' ? 'terminal' : 'blocked',\n retry_count: gap.reason === 'decrypt_error' ? RESTORE_DECRYPT_MAX_RETRIES : 0,\n max_retries: gap.reason === 'decrypt_error' ? RESTORE_DECRYPT_MAX_RETRIES : 0,\n updated_at: gap.updated_at,\n });\n }\n for (const failure of transientByEpoch.values()) {\n const messageVersion = `legacy-epoch:${failure.epoch}:${failure.reason}`;\n repairByVersion.set(messageVersion, {\n cid: record.cid,\n message_id: `legacy-epoch-${failure.epoch}`,\n message_version: messageVersion,\n mls_epoch: failure.epoch,\n reason: 'legacy_epoch_failure',\n status: 'retryable',\n retry_count: failure.retry_count,\n max_retries: failure.max_retries,\n updated_at: failure.updated_at,\n });\n }\n }\n return {\n ...record,\n completed_epochs: completed,\n permanent_gaps: Array.from(permanentByEpoch.values()).sort((a, b) => a.epoch - b.epoch),\n transient_failures: Array.from(transientByEpoch.values()).sort((a, b) => a.epoch - b.epoch),\n repair_issues: Array.from(repairByVersion.values()).sort((a, b) => a.updated_at - b.updated_at),\n };\n }\n\n private _isUserGatedRestoreProgress(record: RestoreProgressRecord): boolean {\n const progress = this._normalizeProgress(record);\n return (\n progress.requires_user_action === 'unlock_recovery_vault' ||\n (progress.target_epochs?.length || 0) > 0 ||\n progress.permanent_gaps.length > 0 ||\n progress.transient_failures.length > 0\n );\n }\n\n private _repairIssuePolicy(reason: RepairIssueReason): {\n status: RepairIssueStatus;\n maxRetries: number;\n } {\n if (reason === 'expired_restore_window') {\n return { status: 'terminal', maxRetries: 0 };\n }\n if (reason === 'forward_secrecy_consumed') {\n return { status: 'blocked', maxRetries: 0 };\n }\n if (reason === 'network_error' || reason === 'server_error') {\n return { status: 'retryable', maxRetries: RESTORE_NETWORK_MAX_RETRIES };\n }\n if (reason === 'decrypt_error') {\n return { status: 'retryable', maxRetries: RESTORE_DECRYPT_MAX_RETRIES };\n }\n if (reason === 'legacy_epoch_failure') {\n return { status: 'retryable', maxRetries: RESTORE_NETWORK_MAX_RETRIES };\n }\n return { status: 'blocked', maxRetries: 0 };\n }\n\n private _upsertRepairIssueInProgress(\n record: RestoreProgressRecord,\n message: {\n id?: string;\n message_id?: string;\n cid?: string;\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n [key: string]: unknown;\n },\n reason: RepairIssueReason,\n incrementRetry = true,\n ): RestoreProgressRecord {\n const messageId = String(message.id || message.message_id || '');\n if (!messageId) return record;\n const normalizedMessage = { ...message, id: messageId };\n const messageVersion = this._messageVersionKey(normalizedMessage);\n const current = (record.repair_issues || []).find((issue) => issue.message_version === messageVersion);\n const policy = this._repairIssuePolicy(reason);\n const retryCount = incrementRetry ? (current?.retry_count || 0) + 1 : current?.retry_count || 0;\n const status =\n policy.status === 'retryable' && retryCount >= policy.maxRetries && policy.maxRetries > 0\n ? 'blocked'\n : policy.status;\n const now = Date.now();\n const issue: RepairIssue = {\n cid: String(message.cid || record.cid),\n message_id: messageId,\n message_version: messageVersion,\n mls_epoch: typeof message.mls_epoch === 'number' ? message.mls_epoch : current?.mls_epoch,\n encrypted_message: message.mls_ciphertext ? { ...message } : current?.encrypted_message,\n created_at: typeof message.created_at === 'string' ? message.created_at : current?.created_at,\n reason,\n status,\n retry_count: retryCount,\n max_retries: policy.maxRetries,\n last_attempt_at: now,\n updated_at: now,\n };\n return this._normalizeProgress({\n ...record,\n repair_issues: [\n ...(record.repair_issues || []).filter((candidate) => candidate.message_version !== messageVersion),\n issue,\n ],\n });\n }\n\n private _clearRepairIssueInProgress(\n record: RestoreProgressRecord,\n message: { id?: string; message_id?: string; created_at?: string; updated_at?: string; mls_epoch?: number },\n ): RestoreProgressRecord {\n const messageId = String(message.id || message.message_id || '');\n if (!messageId) return record;\n const messageVersion = this._messageVersionKey({ ...message, id: messageId });\n return this._normalizeProgress({\n ...record,\n repair_issues: (record.repair_issues || []).filter((issue) => issue.message_version !== messageVersion),\n });\n }\n\n private _upsertLegacyEpochIssue(\n record: RestoreProgressRecord,\n epoch: number,\n reason: RepairIssueReason,\n ): RestoreProgressRecord {\n const messageVersion = `legacy-epoch:${epoch}:${reason}`;\n const policy = this._repairIssuePolicy(reason);\n const current = (record.repair_issues || []).find((issue) => issue.message_version === messageVersion);\n const now = Date.now();\n return this._normalizeProgress({\n ...record,\n repair_issues: [\n ...(record.repair_issues || []).filter((issue) => issue.message_version !== messageVersion),\n {\n cid: record.cid,\n message_id: `legacy-epoch-${epoch}`,\n message_version: messageVersion,\n mls_epoch: epoch,\n reason,\n status: policy.status,\n retry_count: current?.retry_count || 0,\n max_retries: policy.maxRetries,\n last_attempt_at: now,\n updated_at: now,\n },\n ],\n });\n }\n\n private _replaceTargetRepairIssueReason(\n record: RestoreProgressRecord,\n epoch: number,\n reason: RepairIssueReason,\n messageIds?: Set<string>,\n ): RestoreProgressRecord {\n const policy = this._repairIssuePolicy(reason);\n const now = Date.now();\n let replaced = false;\n const repairIssues = (record.repair_issues || []).map((issue) => {\n const matchesMessage =\n messageIds && messageIds.size > 0\n ? messageIds.has(issue.message_id)\n : issue.mls_epoch === epoch && !issue.message_id.startsWith('legacy-epoch-');\n if (!matchesMessage || (issue.mls_epoch !== undefined && issue.mls_epoch !== epoch)) {\n return issue;\n }\n replaced = true;\n return {\n ...issue,\n reason,\n status: policy.status,\n max_retries: policy.maxRetries,\n last_attempt_at: now,\n updated_at: now,\n };\n });\n return replaced\n ? this._normalizeProgress({ ...record, repair_issues: repairIssues })\n : this._upsertLegacyEpochIssue(record, epoch, reason);\n }\n\n private async _recordRepairIssue(\n cid: string,\n message: Record<string, unknown>,\n reason: RepairIssueReason,\n incrementRetry = true,\n ): Promise<void> {\n if (!this.userId || !this.deviceId) return;\n const channel = this._getActiveChannel(cid);\n const parts = channel\n ? { channelType: channel.type as string, channelId: channel.id as string }\n : channelPartsFromCid(cid);\n if (!parts) return;\n let progress = await this._loadOrCreateRestoreProgress(parts.channelType, parts.channelId);\n progress = this._upsertRepairIssueInProgress(progress, { ...message, cid }, reason, incrementRetry);\n await this._saveRestoreProgress(progress, this._finalRestoreStatus(progress));\n }\n\n private async _clearRepairIssue(cid: string, message: Record<string, unknown>): Promise<void> {\n if (!this.userId || !this.deviceId) return;\n const channel = this._getActiveChannel(cid);\n const parts = channel\n ? { channelType: channel.type as string, channelId: channel.id as string }\n : channelPartsFromCid(cid);\n if (!parts) return;\n let progress = await this._loadOrCreateRestoreProgress(parts.channelType, parts.channelId);\n const before = progress.repair_issues?.length || 0;\n progress = this._clearRepairIssueInProgress(progress, message);\n if ((progress.repair_issues?.length || 0) === before) return;\n await this._saveRestoreProgress(progress, this._finalRestoreStatus(progress));\n }\n\n private async _loadOrCreateRestoreProgress(channelType: string, channelId: string): Promise<RestoreProgressRecord> {\n const cid = cidFromParts(channelType, channelId);\n const existing = await this.storage.loadRestoreProgress(this.userId!, this.deviceId!, cid);\n return this._normalizeProgress(existing || this._newRestoreProgressRecord(channelType, channelId));\n }\n\n private async _saveRestoreProgress(\n record: RestoreProgressRecord,\n status?: RestoreStatus,\n ): Promise<RestoreProgressRecord> {\n const next = this._normalizeProgress({\n ...record,\n status: status || record.status,\n last_checked_at: Date.now(),\n updated_at: Date.now(),\n });\n await this.storage.saveRestoreProgress(next);\n this._emitRestoreProgress(next);\n return next;\n }\n\n private _emitRestoreProgress(record: RestoreProgressRecord): void {\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.restore_progress',\n cid: record.cid,\n restore_progress: record,\n status: record.status,\n completed_epochs: record.completed_epochs,\n permanent_gaps: record.permanent_gaps,\n transient_failures: record.transient_failures,\n repair_issues: record.repair_issues || [],\n } as any);\n }\n\n private _markEpochCompleted(record: RestoreProgressRecord, epoch: number): RestoreProgressRecord {\n const completed = new Set(record.completed_epochs);\n completed.add(epoch);\n return this._normalizeProgress({\n ...record,\n completed_epochs: Array.from(completed),\n permanent_gaps: record.permanent_gaps.filter((gap) => gap.epoch !== epoch),\n transient_failures: record.transient_failures.filter((failure) => failure.epoch !== epoch),\n });\n }\n\n private _addPermanentGap(\n record: RestoreProgressRecord,\n epoch: number,\n reason: RestorePermanentGapReason,\n ): RestoreProgressRecord {\n return this._normalizeProgress({\n ...record,\n completed_epochs: record.completed_epochs.filter((completed) => completed !== epoch),\n permanent_gaps: [\n ...record.permanent_gaps.filter((gap) => gap.epoch !== epoch),\n { epoch, reason, updated_at: Date.now() },\n ],\n transient_failures: record.transient_failures.filter((failure) => failure.epoch !== epoch),\n });\n }\n\n private _addTransientFailure(\n record: RestoreProgressRecord,\n epoch: number,\n reason: RestoreTransientFailureReason,\n ): RestoreProgressRecord {\n const existing = record.transient_failures.find((failure) => failure.epoch === epoch);\n const maxRetries = reason === 'decrypt_error' ? RESTORE_DECRYPT_MAX_RETRIES : RESTORE_NETWORK_MAX_RETRIES;\n const retryCount = (existing?.retry_count || 0) + 1;\n if (retryCount >= maxRetries && reason === 'decrypt_error') {\n return this._addPermanentGap(record, epoch, 'decrypt_error');\n }\n return this._normalizeProgress({\n ...record,\n completed_epochs: record.completed_epochs.filter((completed) => completed !== epoch),\n transient_failures: [\n ...record.transient_failures.filter((failure) => failure.epoch !== epoch),\n { epoch, reason, retry_count: retryCount, max_retries: maxRetries, updated_at: Date.now() },\n ],\n });\n }\n\n private _finalRestoreStatus(record: RestoreProgressRecord): RestoreStatus {\n const repairIssues = record.repair_issues || [];\n if (repairIssues.some((issue) => issue.status === 'retryable')) return 'failed';\n const retryable = record.transient_failures.some((failure) => failure.retry_count < failure.max_retries);\n if (retryable) return 'failed';\n if (repairIssues.length > 0) return 'done_with_gaps';\n if (record.transient_failures.length > 0) return 'done_with_gaps';\n return record.permanent_gaps.length > 0 ? 'done_with_gaps' : 'done';\n }\n\n private _markManualRepairIssuesMissingArchives(\n record: RestoreProgressRecord,\n serverEpochs: number[],\n options?: RestoreExecutionOptions,\n ): RestoreProgressRecord {\n if (!options?.manualRepair) return record;\n const serverEpochSet = new Set(serverEpochs);\n const selectedEpochs = options.targetEpochs ? new Set(options.targetEpochs) : null;\n const missingEpochs = new Set<number>();\n\n for (const issue of record.repair_issues || []) {\n if (issue.status === 'terminal' || issue.mls_epoch === undefined) continue;\n if (options.messageIds && !options.messageIds.has(issue.message_id)) continue;\n if (selectedEpochs && !selectedEpochs.has(issue.mls_epoch)) continue;\n if (!serverEpochSet.has(issue.mls_epoch)) missingEpochs.add(issue.mls_epoch);\n }\n\n let next = record;\n for (const epoch of missingEpochs) {\n next = this._addPermanentGap(next, epoch, 'no_archive');\n next = this._replaceTargetRepairIssueReason(next, epoch, 'no_archive', options.messageIds);\n }\n return next;\n }\n\n private async _normalizeStaleRestoreProgress(): Promise<void> {\n if (!this.userId || !this.deviceId || !this.storage) return;\n const running = await this.storage.loadIncompleteRestores(this.userId, this.deviceId);\n await Promise.all(\n running\n .filter((record) => record.status === 'running')\n .map((record) => this._saveRestoreProgress(record, 'partial')),\n );\n }\n\n async getRestoreProgress(channelType: string, channelId: string): Promise<RestoreProgressRecord | null> {\n if (!this.userId || !this.deviceId) return null;\n const cid = cidFromParts(channelType, channelId);\n const record = await this.storage.loadRestoreProgress(this.userId, this.deviceId, cid);\n return record ? this._normalizeProgress(record) : null;\n }\n\n private _restoreRequestKey(cid: string, options?: { fromEpoch?: number; toEpoch?: number }): string {\n return `${cid}:${options?.fromEpoch ?? ''}:${options?.toEpoch ?? ''}`;\n }\n\n private _hasInflightRestoreForCid(cid: string): boolean {\n const prefix = `${cid}:`;\n for (const key of this._restoreInflight.keys()) {\n if (key.startsWith(prefix)) return true;\n }\n return false;\n }\n\n private async _shouldSkipRestoreEnqueue(\n cid: string,\n options?: { fromEpoch?: number; toEpoch?: number },\n ): Promise<boolean> {\n if (options?.fromEpoch !== undefined || options?.toEpoch !== undefined) return false;\n if (this._hasInflightRestoreForCid(cid)) return true;\n if (!this.userId || !this.deviceId) return false;\n\n try {\n const record = await this.storage.loadRestoreProgress(this.userId, this.deviceId, cid);\n if (!record) return false;\n const status = this._normalizeProgress(record).status;\n return status === 'done' || status === 'done_with_gaps';\n } catch (err) {\n sdkLog('warn', '[Encryption] Restore progress check failed before enqueue:', cid, err);\n return false;\n }\n }\n\n private async _enqueueRestoreIfNeeded(entry: RestoreQueueEntry): Promise<void> {\n if (this._hasInflightRestoreForCid(entry.cid)) return;\n if (await this._shouldSkipRestoreEnqueue(entry.cid, entry.options)) return;\n if (this._hasInflightRestoreForCid(entry.cid)) return;\n\n this._restoreQueue = this._restoreQueue.filter((queued) => queued.cid !== entry.cid);\n if (entry.priority === 'active') this._restoreQueue.unshift(entry);\n else this._restoreQueue.push(entry);\n void this._drainRestoreQueue();\n }\n\n enqueueRestore(\n channelType: string,\n channelId: string,\n priority: 'active' | 'background' = 'background',\n options?: { fromEpoch?: number; toEpoch?: number },\n ): void {\n const cid = cidFromParts(channelType, channelId);\n void this._enqueueRestoreIfNeeded({ cid, channelType, channelId, priority, options });\n }\n\n private async _enqueueIncompleteRestores(): Promise<void> {\n await this.bootstrapKnownE2eeChannels({ source: 'manual' });\n const records = await this.storage.loadIncompleteRestores(this.userId!, this.deviceId!);\n const queued = new Set<string>();\n for (const record of records) {\n if (record.status === 'done' || record.status === 'done_with_gaps') continue;\n if (!this.groups.has(record.cid)) continue;\n queued.add(record.cid);\n await this._enqueueRestoreIfNeeded({\n cid: record.cid,\n channelType: record.channel_type,\n channelId: record.channel_id,\n priority: 'background',\n });\n }\n\n for (const channel of this._listKnownE2eeChannels()) {\n if (queued.has(channel.cid)) continue;\n if (!this.groups.has(channel.cid)) continue;\n await this._enqueueRestoreIfNeeded({\n cid: channel.cid,\n channelType: channel.channelType,\n channelId: channel.channelId,\n priority: 'background',\n });\n }\n }\n\n private async _drainRestoreQueue(): Promise<void> {\n if (this._restoreQueueRunning) return;\n this._restoreQueueRunning = true;\n try {\n while (this._restoreQueue.length > 0) {\n const entry = this._restoreQueue.shift()!;\n try {\n await this.restoreHistoricalMessages(entry.channelType, entry.channelId, entry.options);\n } catch (err) {\n sdkLog('warn', '[Encryption] Restore queue entry failed:', entry.cid, err);\n if (!this._recoveryPrivateKey) break;\n }\n }\n } finally {\n this._restoreQueueRunning = false;\n }\n }\n\n private async _withRecoveryNetworkRetry<T>(operation: () => Promise<T>): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt < RESTORE_NETWORK_MAX_RETRIES; attempt += 1) {\n try {\n return await operation();\n } catch (err) {\n lastError = err;\n if (!isRetryableRecoveryNetworkError(err) || attempt + 1 >= RESTORE_NETWORK_MAX_RETRIES) break;\n await new Promise((resolve) => setTimeout(resolve, Math.min(250 * 2 ** attempt, 4_000)));\n }\n }\n throw lastError;\n }\n\n async restoreHistoricalMessages(\n channelType: string,\n channelId: string,\n options?: { fromEpoch?: number; toEpoch?: number },\n ): Promise<RestoredMessage[]> {\n if (!this._recoveryPrivateKey) {\n throw new Error('Recovery vault not unlocked.');\n }\n const requestedCid = cidFromParts(channelType, channelId);\n const restoreKey = this._restoreRequestKey(requestedCid, options);\n const existingRestore = this._restoreInflight.get(restoreKey);\n if (existingRestore) {\n return existingRestore;\n }\n\n const restorePromise = this._restoreHistoricalMessagesInternal(channelType, channelId, options);\n this._restoreInflight.set(restoreKey, restorePromise);\n try {\n return await restorePromise;\n } finally {\n if (this._restoreInflight.get(restoreKey) === restorePromise) {\n this._restoreInflight.delete(restoreKey);\n }\n }\n }\n\n async repairRecoveryChannel(\n channelType: string,\n channelId: string,\n options: { mode?: RepairMode; flushPending?: boolean } = {},\n ): Promise<RepairResult> {\n if (!this._recoveryPrivateKey) {\n throw new Error('Recovery vault not unlocked.');\n }\n\n const mode = options.mode || 'failed_only';\n const requestedCid = cidFromParts(channelType, channelId);\n const shouldFlushPending = options.flushPending !== false;\n const pendingBefore = shouldFlushPending\n ? this._dedupePendingSnapshots(await this.storage.loadPendingE2eeSnapshots(requestedCid))\n : [];\n const flushed = shouldFlushPending\n ? await this._flushPendingE2eeSnapshots(requestedCid)\n : { decrypted: [], pending: [] };\n const pendingVersionById = new Map(pendingBefore.map((snapshot) => [snapshot.message_id, snapshot.version]));\n const newlyRepairedByVersion = new Map<string, RepairMessageResult>();\n for (const message of flushed.decrypted) {\n const messageVersion =\n pendingVersionById.get(message.id) ||\n this._messageVersionKey({\n id: message.id,\n created_at: message.created_at,\n updated_at: message.updated_at,\n });\n newlyRepairedByVersion.set(messageVersion, {\n messageId: message.id,\n messageVersion,\n createdAt: message.created_at,\n });\n }\n\n let progress = await this._loadOrCreateRestoreProgress(channelType, channelId);\n const repairableIssues = (progress.repair_issues || []).filter((issue) => issue.status !== 'terminal');\n const targetEpochs = Array.from(\n new Set(\n repairableIssues\n .map((issue) => issue.mls_epoch)\n .concat(pendingBefore.map((snapshot) => snapshot.mls_epoch))\n .filter((epoch): epoch is number => epoch !== undefined),\n ),\n );\n const messageIds = new Set(\n repairableIssues\n .filter((issue) => !issue.message_id.startsWith('legacy-epoch-'))\n .map((issue) => issue.message_id)\n .concat(pendingBefore.map((snapshot) => snapshot.message_id)),\n );\n\n let restored: RestoredMessage[] = [];\n if (mode === 'recheck_channel' || repairableIssues.length > 0 || flushed.pending.length > 0) {\n restored = await this._restoreHistoricalMessagesInternal(channelType, channelId, {\n forceRecheck: true,\n manualRepair: true,\n timelineOnly: true,\n targetEpochs: mode === 'failed_only' && targetEpochs.length > 0 ? targetEpochs : undefined,\n messageIds: mode === 'failed_only' && messageIds.size > 0 ? messageIds : undefined,\n });\n }\n\n let alreadyAvailable = 0;\n const checked = new Set<string>();\n for (const item of restored) {\n const key = item.messageId || `epoch:${item.epoch}:${item.reason || 'gap'}`;\n checked.add(key);\n if (!item.messageId || item.gap) continue;\n if (item.alreadyAvailable) {\n alreadyAvailable += 1;\n continue;\n }\n const envelope = (item.message || {}) as {\n id?: string;\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n };\n const messageVersion = this._messageVersionKey({\n id: item.messageId,\n created_at: envelope.created_at || item.createdAt,\n updated_at: envelope.updated_at,\n mls_epoch: envelope.mls_epoch ?? item.epoch,\n });\n newlyRepairedByVersion.set(messageVersion, {\n messageId: item.messageId,\n messageVersion,\n epoch: item.epoch,\n createdAt: item.createdAt,\n });\n }\n for (const snapshot of pendingBefore) checked.add(snapshot.message_id);\n\n progress = await this._loadOrCreateRestoreProgress(channelType, channelId);\n return {\n newlyRepaired: Array.from(newlyRepairedByVersion.values()),\n stillFailed: progress.repair_issues || [],\n alreadyAvailable,\n checked: checked.size,\n };\n }\n\n async repairEncryptedChannel(\n channelType: string,\n channelId: string,\n options: { mode?: EncryptedChannelRepairMode } = {},\n ): Promise<EncryptedChannelRepairResult> {\n const requestedCid = cidFromParts(channelType, channelId);\n const requestedChannel = this._getActiveChannel(requestedCid);\n const scopeCid = this._resolveChannelE2eeGroupId(requestedCid, requestedChannel);\n const mode = options.mode || 'replay';\n\n return this._withScopeRepairLock(scopeCid, async () => {\n if (mode === 'reset_local_state') {\n return this._resetEncryptedChannelState(channelType, channelId, requestedCid, scopeCid);\n }\n return this._replayEncryptedChannelState(channelType, channelId, requestedCid, scopeCid);\n });\n }\n\n private async _repairMessagesAfterStateSync(\n channelType: string,\n channelId: string,\n options: { flushPending?: boolean } = {},\n ): Promise<{ requiresPin: boolean; messageRepair?: RepairResult }> {\n if (!this._recoveryPrivateKey) {\n const status = await this.getRecoveryStatus().catch(() => null);\n return { requiresPin: status?.hasVault === true };\n }\n\n const messageRepair = await this.repairRecoveryChannel(channelType, channelId, {\n mode: 'recheck_channel',\n flushPending: options.flushPending,\n });\n return { requiresPin: false, messageRepair };\n }\n\n private _mergeRepairResults(first?: RepairResult, second?: RepairResult): RepairResult | undefined {\n if (!first) return second;\n if (!second) return first;\n const repaired = new Map<string, RepairMessageResult>();\n for (const item of [...first.newlyRepaired, ...second.newlyRepaired]) {\n repaired.set(item.messageVersion, item);\n }\n return {\n newlyRepaired: Array.from(repaired.values()),\n stillFailed: second.stillFailed,\n alreadyAvailable: Math.max(first.alreadyAvailable, second.alreadyAvailable),\n checked: Math.max(first.checked, second.checked),\n };\n }\n\n private async _maxKnownRepairEpoch(\n channelType: string,\n channelId: string,\n requestedCid: string,\n ): Promise<number | undefined> {\n const progress = await this.getRestoreProgress(channelType, channelId).catch(() => null);\n const pending = await this.storage.loadPendingE2eeSnapshots(requestedCid).catch(() => []);\n const epochs = [\n ...((progress?.repair_issues || [])\n .map((issue) => issue.mls_epoch)\n .filter((epoch) => epoch !== undefined) as number[]),\n ...pending.map((snapshot) => snapshot.mls_epoch).filter((epoch) => epoch !== undefined),\n ];\n return epochs.length > 0 ? Math.max(...epochs) : undefined;\n }\n\n private _isLocalEpochBehind(scopeCid: string, targetEpoch?: number): boolean {\n if (targetEpoch === undefined) return false;\n const localEpoch = this._localEpoch(scopeCid);\n return localEpoch !== undefined && localEpoch >= 0 && localEpoch < targetEpoch;\n }\n\n private _encryptedRepairResultFromParts(params: {\n cid: string;\n scopeCid: string;\n status: EncryptedChannelRepairResult['status'];\n requiresPin?: boolean;\n resetAvailable?: boolean;\n syncState?: E2eeSyncState;\n repairState?: ChannelRepairState;\n messageRepair?: RepairResult;\n error?: string;\n }): EncryptedChannelRepairResult {\n const repairedMessages = params.messageRepair?.newlyRepaired.length ?? 0;\n const stillFailed = params.messageRepair?.stillFailed.length ?? 0;\n return {\n cid: params.cid,\n scopeCid: params.scopeCid,\n status: params.status,\n requiresPin: params.requiresPin ?? false,\n resetAvailable: params.resetAvailable ?? false,\n processedEvents: params.syncState?.processed_events ?? 0,\n bufferedMessages: params.syncState?.buffered_messages ?? 0,\n repairedMessages,\n stillFailed,\n messageRepair: params.messageRepair,\n syncState: params.syncState,\n repairState: params.repairState,\n error: params.error,\n };\n }\n\n private async _replayEncryptedChannelState(\n channelType: string,\n channelId: string,\n requestedCid: string,\n scopeCid: string,\n ): Promise<EncryptedChannelRepairResult> {\n let archiveRepairBeforeReplay: RepairResult | undefined;\n let requiresPinBeforeReplay = false;\n let archiveRepairBeforeReplayError: string | undefined;\n try {\n const repairOutcome = await this._repairMessagesAfterStateSync(channelType, channelId, { flushPending: false });\n archiveRepairBeforeReplay = repairOutcome.messageRepair;\n requiresPinBeforeReplay = repairOutcome.requiresPin;\n } catch (err) {\n archiveRepairBeforeReplayError = getApiErrorMessage(err);\n }\n\n const requestedChannel = this._getActiveChannel(requestedCid);\n const scopeChannel = this._getActiveChannel(scopeCid) || requestedChannel;\n const savedCursor = await this._loadScopeSyncCursor(scopeCid);\n const existingState = await this._loadChannelRepairState(scopeCid);\n const maxRepairEpoch = await this._maxKnownRepairEpoch(channelType, channelId, requestedCid);\n const savedCursorTrusted = !this._isLocalEpochBehind(scopeCid, maxRepairEpoch);\n const since =\n existingState?.last_safe_cursor ||\n (scopeChannel\n ? this._membershipBoundedEventCursor(scopeChannel, savedCursorTrusted ? savedCursor : null)\n : savedCursorTrusted\n ? savedCursor || this._nowEventCursor()\n : this._nowEventCursor());\n const replayingState = this._makeChannelRepairState(scopeCid, 'replaying', {\n fail_count: existingState?.fail_count || 0,\n last_safe_cursor: existingState?.last_safe_cursor,\n last_attempted_cursor: since,\n last_committed_cursor: savedCursor || undefined,\n max_observed_epoch: existingState?.max_observed_epoch,\n });\n await this._saveChannelRepairState(replayingState);\n\n let syncState: E2eeSyncState;\n try {\n syncState = await this._syncChannelFromCursor(scopeCid, since, 100);\n } catch (err) {\n const failCount = (existingState?.fail_count || 0) + 1;\n const failedState = this._makeChannelRepairState(\n scopeCid,\n failCount >= CHANNEL_REPAIR_RESET_THRESHOLD ? 'reset_available' : 'replay_failed',\n {\n fail_count: failCount,\n last_safe_cursor: existingState?.last_safe_cursor || since,\n last_attempted_cursor: since,\n last_committed_cursor: savedCursor || undefined,\n max_observed_epoch: existingState?.max_observed_epoch,\n last_error: getApiErrorMessage(err),\n },\n );\n await this._saveChannelRepairState(failedState);\n return this._encryptedRepairResultFromParts({\n cid: requestedCid,\n scopeCid,\n status: failedState.status,\n requiresPin: requiresPinBeforeReplay,\n resetAvailable: failedState.status === 'reset_available',\n repairState: failedState,\n messageRepair: archiveRepairBeforeReplay,\n error: failedState.last_error || archiveRepairBeforeReplayError,\n });\n }\n\n const processedCursor = syncState.processed_event_cursor || since;\n const failCount = syncState.needs_retry ? (existingState?.fail_count || 0) + 1 : 0;\n const repairState = this._makeChannelRepairState(\n scopeCid,\n syncState.needs_retry\n ? failCount >= CHANNEL_REPAIR_RESET_THRESHOLD\n ? 'reset_available'\n : 'replay_failed'\n : 'healthy',\n {\n fail_count: failCount,\n last_safe_cursor: processedCursor,\n last_attempted_cursor: since,\n last_committed_cursor: (await this._loadScopeSyncCursor(scopeCid)) || processedCursor,\n max_observed_epoch:\n Math.max(existingState?.max_observed_epoch || 0, syncState.max_observed_epoch || 0) || undefined,\n last_error: syncState.error,\n },\n );\n await this._saveChannelRepairState(repairState);\n\n if (syncState.needs_retry) {\n let requiresPin = requiresPinBeforeReplay;\n let messageRepair: RepairResult | undefined;\n let messageRepairError: string | undefined;\n try {\n const repairOutcome = await this._repairMessagesAfterStateSync(channelType, channelId);\n requiresPin = repairOutcome.requiresPin;\n messageRepair = this._mergeRepairResults(archiveRepairBeforeReplay, repairOutcome.messageRepair);\n } catch (err) {\n messageRepairError = getApiErrorMessage(err);\n messageRepair = archiveRepairBeforeReplay;\n }\n return this._encryptedRepairResultFromParts({\n cid: requestedCid,\n scopeCid,\n status: repairState.status,\n requiresPin,\n resetAvailable: repairState.status === 'reset_available',\n syncState,\n repairState,\n messageRepair,\n error: repairState.last_error || messageRepairError || archiveRepairBeforeReplayError || syncState.error,\n });\n }\n\n const { requiresPin, messageRepair } = await this._repairMessagesAfterStateSync(channelType, channelId);\n return this._encryptedRepairResultFromParts({\n cid: requestedCid,\n scopeCid,\n status: 'healthy',\n requiresPin,\n resetAvailable: false,\n syncState,\n repairState,\n messageRepair: this._mergeRepairResults(archiveRepairBeforeReplay, messageRepair),\n error: archiveRepairBeforeReplayError,\n });\n }\n\n private async _resetEncryptedChannelState(\n channelType: string,\n channelId: string,\n requestedCid: string,\n scopeCid: string,\n ): Promise<EncryptedChannelRepairResult> {\n const scopeParts = channelPartsFromCid(scopeCid) || { channelType, channelId };\n const existingState = await this._loadChannelRepairState(scopeCid);\n if (existingState?.status !== 'reset_available') {\n throw new Error('Reset encrypted state is only available after protocol replay has failed.');\n }\n const providerSnapshot = this.provider.to_bytes();\n const groupSnapshot = this.groups.get(scopeCid) || null;\n const groupMarkerSnapshot = await this.storage.loadGroupState(scopeCid);\n const pendingSnapshotsSnapshot = await this.storage.loadPendingE2eeSnapshots(scopeCid);\n const savedCursor = await this._loadScopeSyncCursor(scopeCid);\n const resettingState = this._makeChannelRepairState(scopeCid, 'resetting', {\n fail_count: existingState?.fail_count || CHANNEL_REPAIR_RESET_THRESHOLD,\n last_safe_cursor: existingState?.last_safe_cursor,\n last_attempted_cursor: savedCursor || undefined,\n last_committed_cursor: savedCursor || undefined,\n max_observed_epoch: existingState?.max_observed_epoch,\n });\n await this._saveChannelRepairState(resettingState);\n\n try {\n const group = this.groups.get(scopeCid);\n if (group && typeof group.delete_state === 'function') {\n group.delete_state(this.provider);\n }\n this.groups.delete(scopeCid);\n this._pendingEvictions.delete(scopeCid);\n this._channelReadyUntil.delete(scopeCid);\n await this.storage.deleteGroup(scopeCid);\n await this._savePendingSnapshots(scopeCid, []);\n await this._persistPendingEvictions();\n await this._saveEncryptionSyncCheckpoint({ repairStates: [resettingState] });\n\n const joinResult = await this.joinExternal(scopeParts.channelType, scopeParts.channelId, scopeCid);\n const readyResult = await this.syncAfterExternalJoin(scopeParts.channelType, scopeParts.channelId, scopeCid);\n await this._drainArchiveUploadQueue();\n\n const healthyState = this._makeChannelRepairState(scopeCid, 'healthy', {\n fail_count: 0,\n last_safe_cursor: readyResult.sync_state?.processed_event_cursor || savedCursor || undefined,\n last_committed_cursor: (await this._loadScopeSyncCursor(scopeCid)) || savedCursor || undefined,\n max_observed_epoch: Math.max(existingState?.max_observed_epoch || 0, joinResult.epoch || 0) || undefined,\n });\n await this._saveChannelRepairState(healthyState);\n const { requiresPin, messageRepair } = await this._repairMessagesAfterStateSync(channelType, channelId);\n return this._encryptedRepairResultFromParts({\n cid: requestedCid,\n scopeCid,\n status: 'healthy',\n requiresPin,\n resetAvailable: false,\n syncState: readyResult.sync_state,\n repairState: healthyState,\n messageRepair,\n });\n } catch (err) {\n this.provider = wasmModule.Provider.from_bytes(new Uint8Array(providerSnapshot));\n if (groupSnapshot) {\n this.groups.set(scopeCid, groupSnapshot);\n } else {\n this.groups.delete(scopeCid);\n }\n if (groupMarkerSnapshot !== null && groupMarkerSnapshot !== undefined) {\n await this.storage.saveGroupState(scopeCid, groupMarkerSnapshot);\n } else {\n await this.storage.deleteGroup(scopeCid);\n }\n await this._savePendingSnapshots(scopeCid, pendingSnapshotsSnapshot);\n\n const failedState = this._makeChannelRepairState(scopeCid, 'reset_available', {\n fail_count: Math.max(existingState?.fail_count || 0, CHANNEL_REPAIR_RESET_THRESHOLD),\n last_safe_cursor: existingState?.last_safe_cursor,\n last_attempted_cursor: savedCursor || undefined,\n last_committed_cursor: savedCursor || undefined,\n max_observed_epoch: existingState?.max_observed_epoch,\n last_error: getApiErrorMessage(err),\n });\n await this._saveEncryptionSyncCheckpoint({ repairStates: [failedState] });\n return this._encryptedRepairResultFromParts({\n cid: requestedCid,\n scopeCid,\n status: 'failed',\n resetAvailable: true,\n repairState: failedState,\n error: failedState.last_error,\n });\n }\n }\n\n private async _restoreHistoricalMessagesInternal(\n channelType: string,\n channelId: string,\n options?: RestoreExecutionOptions,\n ): Promise<RestoredMessage[]> {\n if (!this._recoveryPrivateKey) {\n throw new Error('Recovery vault not unlocked.');\n }\n const requestedCid = cidFromParts(channelType, channelId);\n const requestedChannel = this._getActiveChannel(requestedCid);\n const archiveCid = this._resolveChannelE2eeGroupId(requestedCid, requestedChannel);\n const archiveParts = channelPartsFromCid(archiveCid) || { channelType, channelId };\n const restoreSingleTimeline = requestedCid !== archiveCid || options?.timelineOnly === true;\n let progress = await this._loadOrCreateRestoreProgress(channelType, channelId);\n const epochListResponse = await this._withRecoveryNetworkRetry(() =>\n this.e2eeClient!.queryEpochArchives(archiveParts.channelType, archiveParts.channelId, {\n list_epochs: true,\n }),\n );\n const selectedEpochs = options?.targetEpochs ? new Set(options.targetEpochs) : null;\n const serverEpochs = Array.from(new Set((epochListResponse.epochs || []).map((entry) => entry.epoch)))\n .filter(\n (epoch) =>\n (!selectedEpochs || selectedEpochs.has(epoch)) &&\n (options?.fromEpoch === undefined || epoch >= options.fromEpoch) &&\n (options?.toEpoch === undefined || epoch <= options.toEpoch),\n )\n .sort((a, b) => a - b);\n const progressAfterMissingArchives = this._markManualRepairIssuesMissingArchives(progress, serverEpochs, options);\n if (progressAfterMissingArchives !== progress) {\n progress = await this._saveRestoreProgress(\n progressAfterMissingArchives,\n this._finalRestoreStatus(progressAfterMissingArchives),\n );\n }\n const completedEpochs = new Set(progress.completed_epochs);\n const permanentGapEpochs = new Set(progress.permanent_gaps.map((gap) => gap.epoch));\n const retryableEpochs = new Set([\n ...progress.transient_failures\n .filter((failure) => failure.retry_count < failure.max_retries)\n .map((failure) => failure.epoch),\n ...(progress.repair_issues || [])\n .filter((issue) => issue.status === 'retryable' && issue.mls_epoch !== undefined)\n .map((issue) => issue.mls_epoch!),\n ]);\n const targetEpochs = serverEpochs\n .filter((epoch) => {\n if (options?.forceRecheck) return true;\n if (retryableEpochs.has(epoch)) return true;\n if (completedEpochs.has(epoch) || permanentGapEpochs.has(epoch)) return false;\n return true;\n })\n .concat(\n Array.from(retryableEpochs).filter(\n (epoch) =>\n serverEpochs.includes(epoch) &&\n (options?.manualRepair || (!completedEpochs.has(epoch) && !permanentGapEpochs.has(epoch))),\n ),\n )\n .filter((epoch, index, all) => all.indexOf(epoch) === index)\n .sort((a, b) => a - b);\n\n if (targetEpochs.length === 0) {\n progress = await this._saveRestoreProgress(progress, this._finalRestoreStatus(progress));\n return [];\n }\n progress = await this._saveRestoreProgress({ ...progress, target_epochs: targetEpochs }, 'running');\n\n const restored: RestoredMessage[] = [];\n const restoredMessagesForStateByCid = new Map<string, Record<string, unknown>[]>();\n const activeEnvelopesByCid = new Map<string, Map<string, ActiveMessageEnvelope>>();\n const getActiveEnvelopes = (routeCid: string): Map<string, ActiveMessageEnvelope> => {\n let activeEnvelopes = activeEnvelopesByCid.get(routeCid);\n if (!activeEnvelopes) {\n activeEnvelopes = this._collectActiveChannelEnvelopes(routeCid);\n activeEnvelopesByCid.set(routeCid, activeEnvelopes);\n }\n return activeEnvelopes;\n };\n const decoder = new TextDecoder();\n for (const epochBatch of splitRestoreEpochBatches(targetEpochs)) {\n const epochFrom = Math.min(...epochBatch);\n const epochTo = Math.max(...epochBatch);\n let material: QueryEpochArchivesResponse;\n const allCiphertexts: HistoricalCiphertext[] = [];\n try {\n material = await this._withRecoveryNetworkRetry(() =>\n this.e2eeClient!.queryEpochArchives(archiveParts.channelType, archiveParts.channelId, {\n epoch_from: epochFrom,\n epoch_to: epochTo,\n include_snapshots: true,\n include_wraps: true,\n }),\n );\n\n let cursor: CiphertextCursor | undefined;\n do {\n const batch = await this._withRecoveryNetworkRetry(() =>\n this.e2eeClient!.queryArchiveCiphertexts(archiveParts.channelType, archiveParts.channelId, {\n epoch_from: epochFrom,\n epoch_to: epochTo,\n cursor,\n limit: 500,\n }),\n );\n allCiphertexts.push(\n ...(restoreSingleTimeline\n ? batch.ciphertexts.filter((ciphertext) => (ciphertext.cid || archiveCid) === requestedCid)\n : batch.ciphertexts\n ).filter((ciphertext) => !options?.messageIds || options.messageIds.has(ciphertext.message_id)),\n );\n cursor = batch.has_more ? batch.next_cursor : undefined;\n } while (cursor);\n } catch (err) {\n const reason: RestoreTransientFailureReason =\n (err as any)?.response?.status >= 500 ? 'server_error' : 'network_error';\n for (const epoch of epochBatch) {\n progress = this._addTransientFailure(progress, epoch, reason);\n progress = this._replaceTargetRepairIssueReason(progress, epoch, reason, options?.messageIds);\n }\n await this._saveRestoreProgress(progress, this._finalRestoreStatus(progress));\n throw err;\n }\n\n const byEpoch = new Map<number, HistoricalCiphertext[]>();\n for (const ciphertext of allCiphertexts) {\n if (!byEpoch.has(ciphertext.mls_epoch)) byEpoch.set(ciphertext.mls_epoch, []);\n byEpoch.get(ciphertext.mls_epoch)!.push(ciphertext);\n }\n\n const wrapsByBlobId = new Map<string, ArchiveKeyWrapRecord>();\n for (const wrap of material.wraps || []) {\n wrapsByBlobId.set(wrap.archive_blob_id, wrap);\n }\n\n for (const epoch of epochBatch) {\n const blobs = (material.blobs || [])\n .filter((blob) => blob.epoch === epoch)\n .sort((left, right) => {\n const leftPriority = left.archive_scope === 'group_sponsored' ? 0 : 1;\n const rightPriority = right.archive_scope === 'group_sponsored' ? 0 : 1;\n if (leftPriority !== rightPriority) return leftPriority - rightPriority;\n return left.created_at.localeCompare(right.created_at);\n });\n if (blobs.length === 0) {\n restored.push({ epoch, gap: true, reason: 'no_archive' });\n progress = this._addPermanentGap(progress, epoch, 'no_archive');\n progress = this._replaceTargetRepairIssueReason(progress, epoch, 'no_archive', options?.messageIds);\n progress = await this._saveRestoreProgress(progress, 'running');\n continue;\n }\n\n type LazyArchiveCandidate = {\n blob: ArchiveBlobRecord;\n wrap: ArchiveKeyWrapRecord;\n prepared: boolean;\n archiveBytes?: Uint8Array;\n snapshotBytes?: Uint8Array;\n prepareError?: 'no_matching_wrap' | 'missing_snapshot';\n };\n const candidates: LazyArchiveCandidate[] = blobs\n .map((blob) => {\n const wrap = wrapsByBlobId.get(blob.archive_blob_id);\n return wrap ? { blob, wrap, prepared: false } : null;\n })\n .filter((candidate): candidate is LazyArchiveCandidate => candidate !== null);\n const prepareCandidate = (candidate: LazyArchiveCandidate): boolean => {\n if (candidate.prepared) return !!candidate.archiveBytes && !!candidate.snapshotBytes;\n candidate.prepared = true;\n const snapshot = material.snapshots?.[candidate.blob.member_snapshot_hash];\n if (!snapshot) {\n candidate.prepareError = 'missing_snapshot';\n return false;\n }\n candidate.snapshotBytes = new Uint8Array(snapshot.snapshot_bytes);\n try {\n const adk = wasmModule.unwrap_archive_data_key_from_parts(\n this.provider,\n this._recoveryPrivateKey,\n new Uint8Array(candidate.wrap.hpke_kem_output),\n new Uint8Array(candidate.wrap.hpke_ciphertext),\n new Uint8Array(candidate.wrap.hpke_info),\n );\n candidate.archiveBytes = wasmModule.decrypt_archive_blob(\n this.provider,\n adk,\n new Uint8Array(candidate.blob.encrypted_archive_bytes),\n new Uint8Array(candidate.blob.aead_nonce),\n new Uint8Array(candidate.blob.aead_aad),\n );\n return true;\n } catch (_) {\n candidate.prepareError = 'no_matching_wrap';\n return false;\n }\n };\n\n if (candidates.length === 0) {\n restored.push({ epoch, gap: true, reason: 'no_matching_wrap' });\n progress = this._addPermanentGap(progress, epoch, 'no_matching_wrap');\n progress = this._replaceTargetRepairIssueReason(progress, epoch, 'no_matching_wrap', options?.messageIds);\n progress = await this._saveRestoreProgress(progress, 'running');\n continue;\n }\n\n progress = this._normalizeProgress({\n ...progress,\n repair_issues: (progress.repair_issues || []).filter(\n (issue) => issue.mls_epoch !== epoch || !issue.message_id.startsWith('legacy-epoch-'),\n ),\n });\n\n for (const ciphertext of byEpoch.get(epoch) || []) {\n const routeCid = ciphertext.cid || requestedCid;\n const activeEnvelope = getActiveEnvelopes(routeCid).get(ciphertext.message_id);\n const envelope = this._buildArchiveMessageEnvelope(routeCid, ciphertext, activeEnvelope, {\n epoch: BigInt(epoch),\n });\n const existingMessage = await this.storage.loadE2eeMessage(ciphertext.message_id);\n if (existingMessage && this._storedMessageCoversVersion(existingMessage, envelope)) {\n progress = this._clearRepairIssueInProgress(progress, envelope);\n restored.push({\n epoch,\n messageId: ciphertext.message_id,\n source: 'archive',\n createdAt: ciphertext.created_at,\n alreadyAvailable: true,\n });\n continue;\n }\n\n let matchedCandidate: LazyArchiveCandidate | undefined;\n let archivedMessage:\n | {\n content: Uint8Array;\n epoch?: bigint;\n generation?: number;\n own_message?: boolean;\n sender_index?: number;\n }\n | undefined;\n for (const candidate of candidates) {\n if (!prepareCandidate(candidate)) continue;\n try {\n archivedMessage = wasmModule.decrypt_with_epoch_archive_v2(\n this.provider,\n candidate.archiveBytes!,\n candidate.snapshotBytes!,\n new Uint8Array(ciphertext.mls_ciphertext),\n true,\n 0,\n );\n matchedCandidate = candidate;\n break;\n } catch (_) {\n // A late archive can have already consumed this generation. Try alternates\n // before recording the message as unavailable.\n }\n }\n\n if (archivedMessage && matchedCandidate) {\n const raw = decoder.decode(archivedMessage.content);\n const parsed = JSON.parse(raw);\n const payload: E2eePayload = parsed && typeof parsed.text === 'string' ? parsed : { text: raw };\n const decryptedEnvelope = this._buildArchiveMessageEnvelope(\n routeCid,\n ciphertext,\n activeEnvelope,\n archivedMessage,\n );\n const storedMessage = {\n ...this._storedFromPayload(routeCid, payload, decryptedEnvelope, existingMessage),\n isRestored: true,\n restoredFrom: 'epoch_archive',\n archiveBlobId: matchedCandidate.blob.archive_blob_id,\n restoredAt: Date.now(),\n restoredEpoch: epoch,\n };\n await this.storage.saveE2eeMessage(storedMessage);\n this._decryptedMsgIds.add(this._messageVersionKey(decryptedEnvelope));\n progress = this._clearRepairIssueInProgress(progress, decryptedEnvelope);\n\n const fullMessage = await this._buildFullMessageWithQuoted(storedMessage, decryptedEnvelope);\n const existing = restoredMessagesForStateByCid.get(routeCid) || [];\n existing.push(fullMessage);\n restoredMessagesForStateByCid.set(routeCid, existing);\n restored.push({\n epoch,\n messageId: ciphertext.message_id,\n plaintext: payload,\n source: 'archive',\n createdAt: ciphertext.created_at,\n message: fullMessage,\n synced: true,\n });\n continue;\n }\n\n const reason: RepairIssueReason = candidates.every(\n (candidate) => candidate.prepareError === 'missing_snapshot',\n )\n ? 'missing_snapshot'\n : candidates.every((candidate) => candidate.prepareError === 'no_matching_wrap')\n ? 'no_matching_wrap'\n : 'decrypt_error';\n progress = this._upsertRepairIssueInProgress(progress, envelope, reason);\n restored.push({ epoch, messageId: ciphertext.message_id, gap: true, reason });\n }\n\n progress = this._markEpochCompleted(progress, epoch);\n progress = await this._saveRestoreProgress(progress, 'running');\n }\n }\n\n progress = await this._saveRestoreProgress(progress, this._finalRestoreStatus(progress));\n\n for (const [routeCid, restoredMessagesForState] of restoredMessagesForStateByCid) {\n if (restoredMessagesForState.length === 0) continue;\n const activeChannel = this.client?.activeChannels?.[routeCid];\n activeChannel?.state?.addMessagesSorted(restoredMessagesForState as any[], false, true, true, 'current');\n this.client?.dispatchEvent({\n type: 'e2ee.local_messages_loaded' as any,\n cid: routeCid,\n messages: restoredMessagesForState,\n } as any);\n }\n\n return restored;\n }\n\n /**\n * Convert a timestamp value to milliseconds.\n * Handles: ISO 8601 string, numeric string, or number.\n * Backward compatible with legacy storage that saved ISO strings.\n */\n /**\n * Extract `created_at` from a sync event.\n * Both variants now store it at `event.data.created_at`:\n * - `application`: `event.data` is a Message (always had `created_at` there)\n * - `protocol`: `event.data` is ProtocolData (now also has `created_at`)\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _getEventCreatedAt(event: any): string | undefined {\n return (\n event?.data?.created_at ||\n event?.created_at ||\n event?.data?.reaction?.created_at ||\n event?.data?.message?.created_at\n );\n }\n\n private _toMillis(value: string | number): number {\n if (typeof value === 'number') return value;\n // If it's a numeric string (e.g. \"1741176000000\"), parse directly\n const num = Number(value);\n if (!isNaN(num) && num > 1_000_000_000_000) return num;\n // Otherwise treat as ISO 8601 date string\n const ms = new Date(value).getTime();\n return isNaN(ms) ? 0 : ms;\n }\n\n private _nowCursor(): string {\n return new Date().toISOString();\n }\n\n private _nowEventCursor(): EventCursor {\n return { created_at: this._nowCursor(), event_id: ZERO_EVENT_ID };\n }\n\n private _toCursorString(value?: string | number | Date | null): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && !Number.isFinite(Number(value))) return value;\n if (value === undefined || value === null) return this._nowCursor();\n const ms = this._toMillis(value);\n return ms ? new Date(ms).toISOString() : this._nowCursor();\n }\n\n private _initialSyncCursor(value?: string | number | null): string {\n if (value === undefined || value === null) return this._nowCursor();\n const ms = this._toMillis(value);\n if (!ms) return this._nowCursor();\n // Bellboy sync uses query_events_after(), so starting exactly at\n // mls_enabled_at can skip protocol events persisted in the same millisecond.\n return new Date(Math.max(0, ms - 1)).toISOString();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _getMembershipCreatedAt(channel: any): string | undefined {\n if (!this.userId || !channel) return undefined;\n\n const membership = channel.state?.membership;\n if (membership?.created_at) return membership.created_at;\n\n const stateMember = channel.state?.members?.[this.userId];\n if (stateMember?.created_at) return stateMember.created_at;\n\n const dataMembers = Array.isArray(channel.data?.members) ? channel.data.members : [];\n const dataMember = dataMembers.find(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (member: any) => member?.user_id === this.userId || member?.user?.id === this.userId,\n );\n return dataMember?.created_at;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _membershipBoundedCursor(channel: any, savedTs?: string | number | null): string {\n const encryptionEnabledAt = channel?.data?.mls_enabled_at;\n const memberCreatedAt = this._getMembershipCreatedAt(channel);\n const candidates: string[] = [];\n\n if (savedTs) candidates.push(this._toCursorString(savedTs));\n if (memberCreatedAt) candidates.push(this._initialSyncCursor(memberCreatedAt));\n if (encryptionEnabledAt) candidates.push(this._initialSyncCursor(encryptionEnabledAt));\n\n if (candidates.length === 0) return this._nowCursor();\n return candidates.reduce((latest, cursor) => (compareRfc3339Cursor(latest, cursor) >= 0 ? latest : cursor));\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _membershipBoundedEventCursor(channel: any, savedCursor?: EventCursor | null): EventCursor {\n const boundedCreatedAt = this._membershipBoundedCursor(channel, savedCursor?.created_at);\n if (savedCursor && compareRfc3339Cursor(boundedCreatedAt, savedCursor.created_at) === 0) {\n return savedCursor;\n }\n return { created_at: boundedCreatedAt, event_id: ZERO_EVENT_ID };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _isE2eeChannelData(data: any): boolean {\n if (data?.mls_enabled === true) return true;\n const parentCid = typeof data?.parent_cid === 'string' ? data.parent_cid : undefined;\n if (!parentCid) return false;\n const parent = this._getActiveChannel(parentCid);\n return parent?.data?.mls_enabled === true || parent?.channel?.mls_enabled === true;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _resolveChannelE2eeGroupId(cid: string, channel?: any): string {\n const data = channel?.data || channel?.channel || channel || {};\n if (typeof data.e2ee_group_id === 'string' && data.e2ee_group_id.length > 0) {\n return data.e2ee_group_id;\n }\n if (typeof data.mls_cid === 'string' && data.mls_cid.length > 0) {\n return data.mls_cid;\n }\n if (\n this._isE2eeChannelData(data) &&\n typeof data.parent_cid === 'string' &&\n data.parent_cid.length > 0 &&\n data.gate !== true\n ) {\n return data.parent_cid;\n }\n return cid;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _resolveMessageE2eeGroupId(message: any, fallbackCid: string): string {\n if (typeof message?.e2ee_group_id === 'string' && message.e2ee_group_id.length > 0) {\n return message.e2ee_group_id;\n }\n if (typeof message?.mls_cid === 'string' && message.mls_cid.length > 0) {\n return message.mls_cid;\n }\n const routeCid = message?.cid || fallbackCid;\n const channel = this._getActiveChannel(routeCid);\n const channelGroupId = this._resolveChannelE2eeGroupId(routeCid, channel);\n return channelGroupId !== routeCid ? channelGroupId : fallbackCid;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _eventRouteCid(event: any, fallbackCid: string): string {\n return event?.cid || event?.data?.cid || event?.data?.message?.cid || fallbackCid;\n }\n\n private _eventCursorFromEnvelope(event: any, fallbackCreatedAt?: string): EventCursor {\n return {\n created_at: event?.created_at || this._getEventCreatedAt(event) || fallbackCreatedAt || this._nowCursor(),\n event_id: event?.event_id || event?.data?.event_id || event?.data?.id || ZERO_EVENT_ID,\n };\n }\n\n private _topicOwnsE2eeGroup(topicCid: string): boolean {\n const topic = this._getActiveChannel(topicCid);\n if (topic?.data?.mls_enabled === false) return false;\n if (this._resolveChannelE2eeGroupId(topicCid, topic) !== topicCid) return false;\n return this.groups.has(topicCid);\n }\n\n private async _loadAllScopeSyncCursors(): Promise<Record<string, EventCursor>> {\n if (this.storage.loadAllScopeSyncCursors) {\n return this.storage.loadAllScopeSyncCursors();\n }\n\n const timestamps = await this.storage.loadAllSyncTimestamps();\n const cursors: Record<string, EventCursor> = {};\n for (const [cid, createdAt] of Object.entries(timestamps)) {\n cursors[cid] = { created_at: createdAt, event_id: ZERO_EVENT_ID };\n }\n return cursors;\n }\n\n private async _saveAllScopeSyncCursors(cursors: Record<string, EventCursor>): Promise<void> {\n if (this.storage.saveAllScopeSyncCursors) {\n await this.storage.saveAllScopeSyncCursors(cursors);\n return;\n }\n\n const timestamps: Record<string, string> = {};\n for (const [cid, cursor] of Object.entries(cursors)) {\n timestamps[cid] = cursor.created_at;\n }\n await this.storage.saveAllSyncTimestamps(timestamps);\n }\n\n private async _loadScopeSyncCursor(cid: string): Promise<EventCursor | null> {\n if (this.storage.loadScopeSyncCursor) {\n return this.storage.loadScopeSyncCursor(cid);\n }\n const timestamp = await this.storage.loadSyncTimestamp(cid);\n return timestamp ? { created_at: timestamp, event_id: ZERO_EVENT_ID } : null;\n }\n\n private async _saveScopeSyncCursor(cid: string, cursor: EventCursor): Promise<void> {\n if (this.storage.saveScopeSyncCursor) {\n await this.storage.saveScopeSyncCursor(cid, cursor);\n return;\n }\n await this.storage.saveSyncTimestamp(cid, cursor.created_at);\n }\n\n private async _loadChannelRepairState(scopeCid: string): Promise<ChannelRepairState | null> {\n if (!this.storage.loadChannelRepairState) return null;\n return this.storage.loadChannelRepairState(scopeCid);\n }\n\n private async _saveChannelRepairState(state: ChannelRepairState): Promise<void> {\n if (!this.storage.saveChannelRepairState) return;\n await this.storage.saveChannelRepairState(state);\n }\n\n private async _deleteChannelRepairState(scopeCid: string): Promise<void> {\n if (!this.storage.deleteChannelRepairState) return;\n await this.storage.deleteChannelRepairState(scopeCid);\n }\n\n private _localEpoch(scopeCid: string): number | undefined {\n const group = this.groups.get(scopeCid);\n if (!group) return undefined;\n try {\n return Number(group.epoch());\n } catch (_) {\n return undefined;\n }\n }\n\n private _makeChannelRepairState(\n scopeCid: string,\n status: ChannelRepairState['status'],\n overrides: Partial<ChannelRepairState> = {},\n ): ChannelRepairState {\n return {\n scope_cid: scopeCid,\n status,\n fail_count: 0,\n local_epoch: this._localEpoch(scopeCid),\n updated_at: Date.now(),\n ...overrides,\n };\n }\n\n private _startScopeRepairGate(scopeCid: string): void {\n if (this._scopeRepairGatePromises.has(scopeCid)) return;\n const promise = new Promise<void>((resolve) => {\n this._scopeRepairGateResolvers.set(scopeCid, resolve);\n });\n this._scopeRepairGatePromises.set(scopeCid, promise);\n }\n\n private _finishScopeRepairGate(scopeCid: string): void {\n const resolve = this._scopeRepairGateResolvers.get(scopeCid);\n this._scopeRepairGateResolvers.delete(scopeCid);\n this._scopeRepairGatePromises.delete(scopeCid);\n resolve?.();\n\n if (this._scopeSyncRequestedAfterRepair.delete(scopeCid)) {\n (async () => {\n const cursor = (await this._loadScopeSyncCursor(scopeCid)) || this._nowEventCursor();\n await this._syncChannelFromCursor(scopeCid, cursor);\n })().catch((err) => {\n sdkLog('warn', '[Encryption] Deferred scope sync after repair failed:', scopeCid, err);\n });\n }\n }\n\n isScopeRepairing(scopeCid: string): boolean {\n return this._scopeRepairGatePromises.has(scopeCid);\n }\n\n requestScopeSyncAfterRepair(scopeCid: string): void {\n this._scopeSyncRequestedAfterRepair.add(scopeCid);\n }\n\n async waitForScopeRepair(scopeCid: string): Promise<void> {\n const promise = this._scopeRepairGatePromises.get(scopeCid);\n if (promise) await promise;\n }\n\n private async _withScopeRepairLock(\n scopeCid: string,\n work: () => Promise<EncryptedChannelRepairResult>,\n ): Promise<EncryptedChannelRepairResult> {\n const existing = this._scopeRepairLocks.get(scopeCid);\n if (existing) return existing;\n\n const promise: Promise<EncryptedChannelRepairResult> = (async () => {\n let softLockAcquired = false;\n if (this.storage.tryAcquireRepairLock) {\n softLockAcquired = await this.storage.tryAcquireRepairLock(\n scopeCid,\n this._repairLockOwnerId,\n CHANNEL_REPAIR_LOCK_TTL_MS,\n );\n if (!softLockAcquired) {\n return {\n cid: scopeCid,\n scopeCid,\n status: 'replay_failed',\n requiresPin: false,\n resetAvailable: false,\n processedEvents: 0,\n bufferedMessages: 0,\n repairedMessages: 0,\n stillFailed: 0,\n error: 'Encrypted state repair is already running for this channel on another tab.',\n };\n }\n }\n\n this._startScopeRepairGate(scopeCid);\n try {\n return await work();\n } finally {\n this._finishScopeRepairGate(scopeCid);\n if (softLockAcquired && this.storage.releaseRepairLock) {\n await this.storage.releaseRepairLock(scopeCid, this._repairLockOwnerId).catch((err) => sdkLog('warn', err));\n }\n }\n })();\n\n this._scopeRepairLocks.set(scopeCid, promise);\n try {\n return await promise;\n } finally {\n if (this._scopeRepairLocks.get(scopeCid) === promise) {\n this._scopeRepairLocks.delete(scopeCid);\n }\n }\n }\n\n private _startSyncGate(): void {\n if (this._syncing && this._syncPromise) return;\n\n this._syncing = true;\n this._syncPromise = new Promise<void>((resolve) => {\n this._syncGateResolve = resolve;\n });\n }\n\n private _finishSyncGate(_err?: unknown): void {\n const resolve = this._syncGateResolve;\n this._syncGateResolve = null;\n this._syncing = false;\n this._syncPromise = null;\n\n // Always resolve the gate so WS decrypt callers can leave the waiting\n // state even when the sync work itself rejects. sync() still throws via\n // _syncWorkPromise for callers that need error handling.\n resolve?.();\n }\n\n private _makeSyncState(\n cid: string,\n status: E2eeSyncStatus,\n startedCursor: string | EventCursor,\n processedCursor: string | EventCursor,\n overrides: Partial<E2eeSyncState> = {},\n ): E2eeSyncState {\n const startedEventCursor =\n typeof startedCursor === 'string' ? { created_at: startedCursor, event_id: ZERO_EVENT_ID } : startedCursor;\n const processedEventCursor =\n typeof processedCursor === 'string' ? { created_at: processedCursor, event_id: ZERO_EVENT_ID } : processedCursor;\n return {\n cid,\n status,\n started_cursor: startedEventCursor.created_at,\n processed_cursor: processedEventCursor.created_at,\n started_event_cursor: startedEventCursor,\n processed_event_cursor: processedEventCursor,\n has_more: false,\n needs_retry: false,\n processed_events: 0,\n buffered_messages: 0,\n ...overrides,\n };\n }\n\n private _emitSyncState(state: E2eeSyncState): void {\n this._lastSyncStates.set(state.cid, state);\n if (!state.needs_retry && state.status !== 'failed' && state.status !== 'stale_group_info') {\n this._channelReadyUntil.set(state.cid, Date.now() + this._channelReadyCacheMs);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.sync_state',\n cid: state.cid,\n sync_state: state,\n } as any);\n }\n\n getSyncState(cid: string): E2eeSyncState | null {\n return this._lastSyncStates.get(cid) || null;\n }\n\n private async _isScopeReadyForOpen(\n scopeCid: string,\n savedCursor?: EventCursor | null,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n channel?: any,\n ): Promise<boolean> {\n if (!this.groups.has(scopeCid)) return false;\n if (this.isScopeRepairing(scopeCid) || this._scopeRepairLocks.has(scopeCid)) return false;\n if (this._scopeSyncRequestedAfterRepair.has(scopeCid)) return false;\n\n const syncState = this.getSyncState(scopeCid);\n if (!syncState || syncState.status !== 'ready' || syncState.needs_retry || syncState.has_more) return false;\n\n const persistedCursor = savedCursor !== undefined ? savedCursor : await this._loadScopeSyncCursor(scopeCid);\n if (!persistedCursor) return false;\n\n let activeChannel = channel;\n if (activeChannel === undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n activeChannel = (this.client as any)?.activeChannels?.[scopeCid];\n }\n if (activeChannel && !this._isE2eeChannelData(activeChannel.data || activeChannel)) return false;\n\n const memberCreatedAt = this._getMembershipCreatedAt(activeChannel);\n if (memberCreatedAt) {\n const membershipCursor = { created_at: this._initialSyncCursor(memberCreatedAt), event_id: ZERO_EVENT_ID };\n if (compareEventCursor(persistedCursor, membershipCursor) < 0) return false;\n }\n\n const processedCursor = syncState.processed_event_cursor || {\n created_at: syncState.processed_cursor,\n event_id: ZERO_EVENT_ID,\n };\n if (compareEventCursor(persistedCursor, processedCursor) < 0) return false;\n\n const repairState = await this._loadChannelRepairState(scopeCid);\n return !repairState || repairState.status === 'healthy';\n }\n\n private _getDurableSyncCursor({\n processedCursor,\n serverNextCursor,\n hasMore,\n }: {\n processedCursor: string;\n serverNextCursor?: string;\n hasMore: boolean;\n bufferedMessages: number;\n }): string {\n if (!hasMore && serverNextCursor !== undefined && compareRfc3339Cursor(serverNextCursor, processedCursor) >= 0) {\n return serverNextCursor;\n }\n\n return processedCursor;\n }\n\n private _resolveProcessedEventCursor(\n processResult: ChannelProcessResult,\n startedCursor: EventCursor,\n serverNextCursor: EventCursor,\n ): { processedEventCursor: EventCursor; cursorLagged: boolean; durableCursor: EventCursor } {\n const processedEventCursor = processResult.processedEventCursor ?? startedCursor;\n const cursorLagged = compareEventCursor(processedEventCursor, serverNextCursor) < 0;\n return {\n processedEventCursor,\n cursorLagged,\n durableCursor: cursorLagged ? processedEventCursor : serverNextCursor,\n };\n }\n\n private _pendingSnapshotVersion(message: {\n id?: string;\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n }): string {\n const version = message.updated_at || message.created_at || '';\n return (message.id || '') + ':' + version + ':' + (message.mls_epoch ?? '');\n }\n\n private _toPendingSnapshot(\n cid: string,\n eventType: 'application' | 'message_updated',\n message: Record<string, unknown>,\n receivedCursor?: string,\n eventTime?: string,\n ): PendingE2eeSnapshot {\n const typedMessage = message as { id?: string; created_at?: string; updated_at?: string; mls_epoch?: number };\n return {\n cid,\n event_type: eventType,\n message_id: String(typedMessage.id || ''),\n mls_epoch: typeof typedMessage.mls_epoch === 'number' ? typedMessage.mls_epoch : undefined,\n message,\n version: this._pendingSnapshotVersion(typedMessage),\n received_cursor: receivedCursor,\n event_time: eventTime,\n };\n }\n\n private _dedupePendingSnapshots(messages: PendingE2eeSnapshot[]): PendingE2eeSnapshot[] {\n const byVersion = new Map<string, PendingE2eeSnapshot>();\n for (const message of messages) {\n if (!message.message_id) continue;\n byVersion.set(message.version, message);\n }\n return Array.from(byVersion.values()).sort((a, b) => compareRfc3339Cursor(a.received_cursor, b.received_cursor));\n }\n\n private async _savePendingSnapshots(cid: string, messages: PendingE2eeSnapshot[]): Promise<void> {\n await this.storage.savePendingE2eeSnapshots(cid, this._dedupePendingSnapshots(messages));\n }\n\n private _pendingSnapshotEventType(message: {\n created_at?: string;\n updated_at?: string;\n }): 'application' | 'message_updated' {\n return message.updated_at && message.updated_at !== message.created_at ? 'message_updated' : 'application';\n }\n\n private _pendingSnapshotCursor(message: { created_at?: string; updated_at?: string }): string {\n return message.updated_at || message.created_at || this._nowCursor();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private async _rememberPendingE2eeSnapshot(routeCid: string, message: Record<string, any>): Promise<void> {\n if (\n typeof (this.storage as any)?.loadPendingE2eeSnapshots !== 'function' ||\n typeof (this.storage as any)?.savePendingE2eeSnapshots !== 'function'\n ) {\n return;\n }\n try {\n const existing = await this.storage.loadPendingE2eeSnapshots(routeCid);\n const cursor = this._pendingSnapshotCursor(message);\n await this._savePendingSnapshots(routeCid, [\n ...existing,\n this._toPendingSnapshot(routeCid, this._pendingSnapshotEventType(message), message, cursor, cursor),\n ]);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to persist pending E2EE snapshot:', routeCid, err);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _pendingRouteCidsForScope(scopeCid: string): string[] {\n const routeCids = new Set<string>([scopeCid]);\n const addIfInScope = (routeCid?: string, channel?: any) => {\n if (!routeCid) return;\n if (routeCid === scopeCid || this._resolveChannelE2eeGroupId(routeCid, channel) === scopeCid) {\n routeCids.add(routeCid);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannels = ((this.client as any)?.activeChannels || {}) as Record<string, any>;\n for (const [routeCid, channel] of Object.entries(activeChannels)) {\n addIfInScope(routeCid, channel);\n const topics = channel?.state?.topics;\n if (!Array.isArray(topics)) continue;\n for (const topic of topics) {\n addIfInScope(topic?.cid || topic?.data?.cid || topic?.channel?.cid, topic);\n }\n }\n\n return Array.from(routeCids);\n }\n\n private _publishDecryptedMessages(decryptedMessages: E2eeStoredMessage[]): void {\n if (decryptedMessages.length === 0) return;\n\n const decryptedByCid = new Map<string, E2eeStoredMessage[]>();\n for (const message of decryptedMessages) {\n const existing = decryptedByCid.get(message.cid) || [];\n existing.push(message);\n decryptedByCid.set(message.cid, existing);\n }\n\n for (const [routeCid, messages] of decryptedByCid) {\n const activeChannel = this._getActiveChannel(routeCid);\n if (activeChannel?.state?.messageSets) {\n const stateUsers = Object.values((this.client as any)?.state?.users || {});\n const messagesForState = messages.map((message) => {\n const stateUser = (this.client as any)?.state?.users?.[message.user_id];\n return {\n ...message,\n content_type: 'standard',\n user: pickUserWithDisplayName(\n message.user_id,\n stateUser,\n message.user,\n getUserInfo(message.user_id, stateUsers),\n message.user_id === this.userId ? this.client?.user : undefined,\n ),\n status: 'received',\n };\n });\n\n if (typeof activeChannel.state.addMessagesSorted === 'function') {\n activeChannel.state.addMessagesSorted(messagesForState, false, true, true, 'latest');\n }\n\n const decryptedById = new Map(messages.map((message) => [message.id, message]));\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n activeChannel.state.messageSets.forEach((messageSet: any) => {\n for (let i = 0; i < messageSet.messages.length; i++) {\n const msg = messageSet.messages[i];\n const dec = decryptedById.get(msg.id);\n if (!dec) continue;\n messageSet.messages[i] = {\n ...msg,\n content_type: 'standard',\n text: dec.text ?? '',\n attachments: dec.attachments ?? msg.attachments,\n sticker_url: dec.sticker_url ?? msg.sticker_url,\n };\n }\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.post_join_sync' as any,\n cid: routeCid,\n messages: messages.map((message) => ({ ...message, content_type: 'standard' })),\n } as any);\n }\n }\n\n private async _flushPendingSnapshotsForScope(\n scopeCid: string,\n ): Promise<{ decrypted: E2eeStoredMessage[]; pending: PendingE2eeSnapshot[] }> {\n if (\n typeof (this.storage as any)?.loadPendingE2eeSnapshots !== 'function' ||\n typeof (this.storage as any)?.savePendingE2eeSnapshots !== 'function'\n ) {\n return { decrypted: [], pending: [] };\n }\n const pendingCids = this._pendingRouteCidsForScope(scopeCid);\n const pendingSnapshots: PendingE2eeSnapshot[] = [];\n\n for (const pendingCid of pendingCids) {\n pendingSnapshots.push(...(await this.storage.loadPendingE2eeSnapshots(pendingCid)));\n }\n\n const retryBatch = this._dedupePendingSnapshots(pendingSnapshots);\n if (retryBatch.length === 0) return { decrypted: [], pending: [] };\n\n const retryMessages = retryBatch.map((snapshot) => ({\n ...(snapshot.message as any),\n cid: snapshot.cid || (snapshot.message as any)?.cid || scopeCid,\n }));\n const { decrypted, buffered } = await this.decryptApplicationMessages(scopeCid, retryMessages);\n const bufferedVersions = new Set(buffered.map((message: any) => this._pendingSnapshotVersion(message)));\n const stillPending = retryBatch.filter((snapshot) => bufferedVersions.has(snapshot.version));\n const cidsToSave = new Set<string>([\n ...pendingCids,\n ...retryBatch.map((snapshot) => snapshot.cid || scopeCid),\n ...stillPending.map((snapshot) => snapshot.cid || scopeCid),\n ]);\n const pendingByRouteCid = new Map<string, PendingE2eeSnapshot[]>();\n\n for (const snapshot of stillPending) {\n const routeCid = snapshot.cid || scopeCid;\n const existing = pendingByRouteCid.get(routeCid) || [];\n existing.push(snapshot);\n pendingByRouteCid.set(routeCid, existing);\n }\n\n for (const pendingCid of cidsToSave) {\n await this._savePendingSnapshots(pendingCid, pendingByRouteCid.get(pendingCid) || []);\n }\n\n this._publishDecryptedMessages(decrypted);\n return { decrypted, pending: stillPending };\n }\n\n private async _flushPendingE2eeSnapshots(\n cid: string,\n ): Promise<{ decrypted: E2eeStoredMessage[]; pending: PendingE2eeSnapshot[] }> {\n const pending = this._dedupePendingSnapshots(await this.storage.loadPendingE2eeSnapshots(cid));\n if (pending.length === 0) return { decrypted: [], pending: [] };\n\n const { decrypted, buffered } = await this.decryptApplicationMessages(\n cid,\n pending.map((snapshot) => snapshot.message as any),\n );\n const bufferedVersions = new Set(buffered.map((message: any) => this._pendingSnapshotVersion(message)));\n const stillPending = pending.filter((snapshot) => bufferedVersions.has(snapshot.version));\n await this._savePendingSnapshots(cid, stillPending);\n return { decrypted, pending: stillPending };\n }\n\n /**\n * Sync encryption protocol events for all E2EE channels and restore groups.\n *\n * On page reload, WASM groups are lost (in-memory only).\n * 1. Restore groups from Provider storage.\n * 2. For each restored group, call server sync API to catch up on\n * missed protocol events (commits, welcomes) since last sync.\n */\n /**\n * Public sync — catch up on missed protocol + application events.\n * Called on reconnect (recoverState) and can be called manually.\n *\n * Tracks syncing state so that WS event handlers can detect when sync\n * is in progress and retry failed decryptions after sync completes.\n */\n async sync(): Promise<void> {\n if (this._syncWorkPromise) {\n return this._syncWorkPromise;\n }\n\n this._startSyncGate();\n this._syncWorkPromise = this._syncAndRestoreGroups()\n .then(() => {\n this._finishSyncGate();\n })\n .catch((err) => {\n this._finishSyncGate(err);\n throw err;\n })\n .finally(() => {\n this._syncWorkPromise = null;\n });\n\n return this._syncWorkPromise;\n }\n\n /** Whether an encryption sync is currently in progress (reconnect catch-up). */\n isSyncing(): boolean {\n return this._syncing;\n }\n\n /** Returns a promise that resolves when the current sync completes (or immediately if not syncing). */\n waitForSync(): Promise<void> {\n return this._syncPromise || Promise.resolve();\n }\n\n /**\n * Mark sync as started EARLY — before queryChannels or any other async work.\n * This prevents WS message.new events from consuming ratchet secrets during\n * the window between _connect() and sync().\n */\n markSyncStart(): void {\n this._startSyncGate();\n }\n\n private async _syncAndRestoreGroups(): Promise<void> {\n try {\n // Step 1: Restore groups from Provider storage using saved CID list\n const savedCids = await this.storage.listGroupCids();\n if (savedCids.length > 0) {\n sdkLog('info', `[Encryption] Restoring ${savedCids.length} group(s) from Provider...`);\n for (const cid of savedCids) {\n if (this.groups.has(cid)) continue;\n try {\n const group = wasmModule.Group.load(this.provider, cid);\n this.groups.set(cid, group);\n sdkLog('info', '[Encryption] Restored group:', cid);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to restore group:', cid, err);\n }\n }\n }\n\n // Load persisted pending evictions from previous session.\n // These survive reconnects even after the sync cursor has advanced past\n // the SystemMessage type 12 that originally triggered them.\n try {\n const persisted = await this.storage.loadPendingEvictions();\n for (const [cid, userIds] of Object.entries(persisted)) {\n const existing = this._pendingEvictions.get(cid) ?? new Set<string>();\n for (const uid of userIds) existing.add(uid);\n this._pendingEvictions.set(cid, existing);\n }\n if (Object.keys(persisted).length > 0) {\n sdkLog('info', '[Encryption] Restored pending evictions from storage:', persisted);\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to load persisted evictions:', err);\n }\n\n // Step 2: Sync all encryption scopes via scope_sync.\n const savedCursors = await this._loadAllScopeSyncCursors();\n let removedCursor = await this.storage.loadRemovedSyncCursor();\n const groupCids = Array.from(this.groups.keys());\n\n // Build cursor map bounded by the current membership. On re-invite this\n // prevents replaying protocol events from the old membership.\n const syncCursors: Record<string, EventCursor> = {};\n for (const cid of groupCids) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n syncCursors[cid] = this._membershipBoundedEventCursor(channel, savedCursors[cid]);\n }\n\n if (Object.keys(syncCursors).length === 0) {\n sdkLog('info', '[Encryption] No existing channels to sync — will check for external join');\n }\n\n // Paginated sync loop. It also carries removed_cursor, so keep calling\n // even when no channel cursor exists locally.\n let hasMore = true;\n while (hasMore) {\n hasMore = false;\n const response = await this.e2eeClient!.scopeSync(syncCursors, 100, removedCursor ?? null);\n\n const removedChannels = response.removed_channels;\n if (removedChannels?.events?.length) {\n for (const tombstone of removedChannels.events) {\n await this._processRemovedChannelTombstone(tombstone);\n }\n }\n if (\n removedChannels?.next_cursor !== undefined &&\n isRemovedCursorAfter(removedChannels.next_cursor, removedCursor)\n ) {\n removedCursor = removedChannels.next_cursor;\n await this.storage.saveRemovedSyncCursor(removedCursor);\n }\n if (removedChannels?.has_more) {\n hasMore = true;\n }\n\n for (const [scopeCid, channelResult] of Object.entries(response.channels || {})) {\n if (!channelResult?.events || channelResult.events.length === 0) {\n const flushed = await this._flushPendingSnapshotsForScope(scopeCid);\n const currentCursor = syncCursors[scopeCid] ?? this._nowEventCursor();\n this._emitSyncState(\n this._makeSyncState(\n scopeCid,\n channelResult.has_more ? 'syncing' : 'ready',\n currentCursor,\n currentCursor,\n {\n server_next_cursor: channelResult.next_cursor?.created_at,\n server_next_event_cursor: channelResult.next_cursor,\n has_more: channelResult.has_more,\n needs_retry: channelResult.has_more,\n processed_events: 0,\n buffered_messages: flushed.pending.length,\n },\n ),\n );\n if (channelResult.has_more) {\n hasMore = true;\n }\n continue;\n }\n\n const startedCursor = syncCursors[scopeCid] ?? this._nowEventCursor();\n const processResult = await this._processChannelEvents(scopeCid, channelResult.events, startedCursor);\n const fallbackNextCursor = this._eventCursorFromEnvelope(\n channelResult.events[channelResult.events.length - 1],\n startedCursor.created_at,\n );\n const serverNextCursor = channelResult.next_cursor ?? fallbackNextCursor;\n const { processedEventCursor, cursorLagged, durableCursor } = this._resolveProcessedEventCursor(\n processResult,\n startedCursor,\n serverNextCursor,\n );\n const processedCursor = processedEventCursor.created_at;\n const retryNeeded = channelResult.has_more || cursorLagged;\n\n if (compareEventCursor(durableCursor, startedCursor) > 0) {\n syncCursors[scopeCid] = durableCursor;\n }\n\n this._emitSyncState(\n this._makeSyncState(\n scopeCid,\n cursorLagged ? 'needs_retry' : channelResult.has_more ? 'syncing' : 'ready',\n startedCursor,\n processedEventCursor,\n {\n server_next_cursor: serverNextCursor.created_at,\n server_next_event_cursor: serverNextCursor,\n has_more: channelResult.has_more,\n needs_retry: retryNeeded,\n processed_events: processResult.processedEvents,\n buffered_messages: processResult.bufferedMessages,\n max_observed_epoch: processResult.maxObservedEpoch,\n },\n ),\n );\n\n if (channelResult.has_more && !cursorLagged) {\n hasMore = true;\n }\n }\n }\n\n await this._saveEncryptionSyncCheckpoint({ scopeCursors: syncCursors });\n\n sdkLog('info', `[Encryption] Sync complete. Groups: ${this.groups.size}`);\n\n // Pending evictions are intentionally deferred. The next encryption membership\n // commit bundles them through _collectPendingGhosts(); sync itself must\n // not submit commit_eviction immediately after an invite reject.\n\n // Step 3: Multi-device — external join for E2EE channels without local group\n // On a new device, no groups are restored from storage.\n // Scan all activeChannels and external join any E2EE channel missing a local group.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannels = (this.client as any)?.activeChannels as Record<string, any> | undefined;\n if (activeChannels) {\n const missingCids: Array<{ cid: string; type: string; id: string }> = [];\n for (const [cid, channel] of Object.entries(activeChannels)) {\n if (\n this._isE2eeChannelData(channel?.data || channel) &&\n this._resolveChannelE2eeGroupId(cid, channel) === cid &&\n !this.groups.has(cid)\n ) {\n missingCids.push({ cid, type: channel.type, id: channel.id });\n }\n }\n\n if (missingCids.length > 0) {\n sdkLog('info', `[Encryption] Multi-device: ${missingCids.length} E2EE channel(s) need external join`);\n // External join sequentially to avoid race conditions on Provider snapshot\n for (const { cid, type, id } of missingCids) {\n try {\n const result = await this.syncNewChannel(type, id, cid);\n sdkLog('info', '[Encryption] Multi-device ensure completed:', cid, result.status);\n } catch (err) {\n sdkLog('warn', '[Encryption] Multi-device external join failed:', cid, err);\n }\n }\n }\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to sync and restore groups:', err);\n }\n }\n\n /**\n * Process sync events for a single channel (protocol + application messages).\n * Events are already sorted by the server.\n */\n private async _processRemovedChannelTombstone(tombstone: {\n event_id?: string;\n cid: string;\n channel_id?: string;\n channel_type?: string;\n parent_cid?: string;\n removed_at?: string;\n removed_by?: string;\n removal_type?: string;\n reason?: string | null;\n self_remove?: boolean;\n }): Promise<void> {\n const cid = tombstone.cid;\n if (!cid) return;\n\n this.leaveGroup(cid, tombstone.removed_at);\n this._pendingEvictions.delete(cid);\n await this._persistPendingEvictions();\n await this._savePendingSnapshots(cid, []);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannels = (this.client as any)?.activeChannels;\n if (activeChannels?.[cid]) {\n delete activeChannels[cid];\n }\n\n sdkLog('info', '[Encryption] Removed channel tombstone processed:', cid, {\n removed_at: tombstone.removed_at,\n removed_by: tombstone.removed_by,\n removal_type: tombstone.removal_type,\n self_remove: tombstone.self_remove,\n });\n }\n\n private async _processChannelEvents(\n cid: string,\n events: any[],\n startedCursor: EventCursor = this._nowEventCursor(),\n ): Promise<ChannelProcessResult> {\n const scopeCid = cid;\n const decryptedMessages: E2eeStoredMessage[] = [];\n const pendingEncryptionMessages: PendingE2eeSnapshot[] = [];\n let processedEvents = 0;\n let lastSafeEventCursor = startedCursor;\n let maxObservedEpoch: number | undefined;\n const pendingCids = new Set<string>(this._pendingRouteCidsForScope(scopeCid));\n\n const savePendingByRouteCid = async () => {\n const byRouteCid = new Map<string, PendingE2eeSnapshot[]>();\n for (const snapshot of pendingEncryptionMessages) {\n const routeCid = snapshot.cid || scopeCid;\n const existing = byRouteCid.get(routeCid) || [];\n existing.push(snapshot);\n byRouteCid.set(routeCid, existing);\n }\n for (const pendingCid of pendingCids) {\n await this._savePendingSnapshots(pendingCid, byRouteCid.get(pendingCid) || []);\n }\n };\n\n const retryPendingMessages = async () => {\n if (pendingEncryptionMessages.length === 0) return;\n const retryBatch = pendingEncryptionMessages\n .splice(0, pendingEncryptionMessages.length)\n .sort((a, b) => compareRfc3339Cursor(a.received_cursor, b.received_cursor));\n const retryMessages = retryBatch.map((snapshot) => ({\n ...(snapshot.message as any),\n cid: snapshot.cid || (snapshot.message as any)?.cid || scopeCid,\n }));\n const { decrypted, buffered } = await this.decryptApplicationMessages(scopeCid, retryMessages);\n decryptedMessages.push(...decrypted);\n const bufferedVersions = new Set(buffered.map((message: any) => this._pendingSnapshotVersion(message)));\n pendingEncryptionMessages.push(...retryBatch.filter((snapshot) => bufferedVersions.has(snapshot.version)));\n await savePendingByRouteCid();\n };\n\n for (const event of events) {\n pendingCids.add(this._eventRouteCid(event, scopeCid));\n }\n for (const pendingCid of pendingCids) {\n pendingEncryptionMessages.push(...(await this.storage.loadPendingE2eeSnapshots(pendingCid)));\n }\n pendingEncryptionMessages.splice(\n 0,\n pendingEncryptionMessages.length,\n ...this._dedupePendingSnapshots(pendingEncryptionMessages),\n );\n await retryPendingMessages();\n\n for (const event of events) {\n const eventCreatedAt = this._getEventCreatedAt(event);\n const eventCursor = this._eventCursorFromEnvelope(event, lastSafeEventCursor.created_at);\n // Sync response uses event.type as sole discriminator: \"protocol\" | \"application\"\n // Data is always nested in event.data\n const eventType = event.type;\n const routeCid = this._eventRouteCid(event, scopeCid);\n const protocolCid = event?.cid || scopeCid;\n const markEventSafe = () => {\n processedEvents += 1;\n lastSafeEventCursor = eventCursor;\n };\n\n switch (eventType) {\n case 'protocol': {\n const protoMsg = event.data || event.message || event;\n const typeField = protoMsg.type || protoMsg.type_field;\n if (typeof protoMsg.epoch === 'number') {\n maxObservedEpoch = Math.max(maxObservedEpoch ?? protoMsg.epoch, protoMsg.epoch);\n }\n\n switch (typeField) {\n case 'welcome': {\n const targetUserIds = (protoMsg.target_user_ids as string[]) || [];\n if (targetUserIds.includes(this.userId!) && !this.groups.has(protocolCid)) {\n try {\n await this.joinGroup(\n protoMsg.welcome as Uint8Array,\n protoMsg.ratchet_tree as Uint8Array | undefined,\n protoMsg.user?.id,\n );\n } catch (err) {\n if (this._isMissingKeyPackageError(err)) {\n sdkLog('warn', '[Encryption] Skipping stale welcome with no local KeyPackage:', protocolCid, err);\n break;\n }\n throw err;\n }\n }\n break;\n }\n case 'commit':\n case 'external_commit': {\n const protoDeviceId = protoMsg.device_id;\n const protoUserId = protoMsg.user?.id;\n const isOwnDeviceCommit =\n protoUserId === this.userId && !!protoDeviceId && protoDeviceId === this.deviceId;\n\n if (isOwnDeviceCommit) {\n sdkLog('info', `[Encryption] Skipping own ${typeField} (already merged):`, protocolCid);\n break;\n }\n\n if (!this.groups.has(protocolCid)) {\n sdkLog('info', `[Encryption] Skipping ${typeField} before local group exists:`, protocolCid);\n break;\n }\n\n // Pre-check: if group epoch already advanced past this commit's epoch,\n // the commit was already applied (e.g. we merged it before last reload).\n // Do NOT call group.process_message() — for ExternalCommit, OpenMLS\n // returns an AEAD error (not epoch mismatch) which corrupts ratchet state.\n const commitEventEpoch: number = protoMsg.epoch ?? -1;\n const currentGroup = this.groups.get(protocolCid);\n if (currentGroup && commitEventEpoch >= 0) {\n const groupEpoch = Number(currentGroup.epoch());\n if (groupEpoch >= commitEventEpoch) {\n sdkLog(\n 'info',\n `[Encryption] processCommit: commit at epoch ${commitEventEpoch} already applied (group at ${groupEpoch}), skipping:`,\n protocolCid,\n );\n break;\n }\n }\n const commit = protoMsg.commit;\n await this.processCommit(protocolCid, commit as Uint8Array, commitEventEpoch, protoUserId, {\n flushPending: false,\n });\n break;\n }\n }\n await retryPendingMessages();\n break;\n }\n case 'application': {\n // Application message — data nested in event.data\n const msg = event.data || event.message;\n const contentType = msg.content_type;\n\n if (contentType === 'mls') {\n // encryption encrypted message — decrypt at its actual timeline position.\n // If epoch state is not ready yet, persist it and let the durable cursor\n // advance. Pending snapshots are retried after later commits advance the group.\n const groupCid = this._resolveMessageE2eeGroupId(msg, scopeCid);\n const { decrypted, buffered } = await this.decryptApplicationMessages(routeCid, [msg], groupCid);\n decryptedMessages.push(...decrypted);\n if (buffered.length > 0) {\n pendingEncryptionMessages.push(\n ...buffered.map((bufferedMessage: any) =>\n this._toPendingSnapshot(\n routeCid,\n 'application',\n bufferedMessage,\n eventCursor.created_at,\n eventCreatedAt,\n ),\n ),\n );\n await savePendingByRouteCid();\n }\n } else {\n // Standard/system message — save directly, no decryption needed\n await this.storage.saveE2eeMessage({\n id: msg.id,\n cid: routeCid,\n content_type: 'standard',\n text: msg.text || '',\n user_id: msg.user?.id || '',\n user: msg.user ? { ...msg.user } : undefined,\n created_at: msg.created_at || new Date().toISOString(),\n type: msg.message_type || msg.type || 'system',\n parent_id: msg.parent_id,\n quoted_message_id: msg.quoted_message_id,\n mentioned_users: msg.mentioned_users,\n });\n\n // ── Legacy offline recovery fallback: Self-remove (SystemMessage types 11, 12, 21) ──\n // When the designated evictor was offline while C self-left or rejected\n // invite, they missed the WS event. Queue only on the designated evictor;\n // normal members must not submit commit_eviction during sync recovery.\n // Typed notification sync events are the primary signal for invite_rejected.\n // 11: InviteRejected, 12: MemberLeaved, 21: InviteMessagingRejected\n const msgText: string = msg.text || '';\n if (\n (msg.message_type === 'system' || msg.type === 'system') &&\n (msgText.startsWith('12 ') || msgText.startsWith('11 ') || msgText.startsWith('21 '))\n ) {\n const leftUserId = msgText.split(' ')[1];\n if (leftUserId && leftUserId !== this.userId) {\n const e2eeGroupId = this._resolveChannelE2eeGroupId(routeCid, this._getActiveChannel(routeCid));\n const activeChannel = this._getActiveChannel(routeCid) || this._getActiveChannel(e2eeGroupId);\n if (!activeChannel || !this.isDesignatedEvictor(activeChannel)) {\n markEventSafe();\n continue;\n }\n const group = this.groups.get(e2eeGroupId);\n if (group) {\n // Check C still has leaf nodes (another evictor may have already removed them)\n try {\n const leafNodes = group.members_by_user_id(leftUserId);\n if (leafNodes && leafNodes.length > 0) {\n // Queue the eviction to be bundled into the next commit action\n // (add/remove/rotate).\n const queue = this._pendingEvictions.get(e2eeGroupId) ?? new Set<string>();\n queue.add(leftUserId);\n this._pendingEvictions.set(e2eeGroupId, queue);\n sdkLog(\n 'info',\n '[Encryption] Queued eviction (offline recovery) for',\n leftUserId,\n 'in',\n e2eeGroupId,\n );\n // Persist immediately so the queue survives a crash/reconnect\n // even after the sync cursor has advanced past this SystemMessage.\n this._persistPendingEvictions().catch((err) => sdkLog('warn', err));\n }\n } catch (_err) {\n // members_by_user_id may fail if group is in invalid state — safe to ignore\n }\n }\n }\n }\n }\n break;\n }\n case 'invite_rejected': {\n const rejectData = event.data || {};\n const rejectedUserId = rejectData.member?.user_id;\n if (!rejectedUserId) break;\n\n const eventGroupId = this._resolveChannelE2eeGroupId(routeCid, this._getActiveChannel(routeCid));\n const activeChannel = this._getActiveChannel(routeCid) || this._getActiveChannel(eventGroupId);\n if (activeChannel?.state?.members) {\n delete activeChannel.state.members[rejectedUserId];\n }\n\n if (rejectedUserId === this.userId) {\n this.leaveGroup(eventGroupId, eventCreatedAt);\n for (const topicCid of rejectData.topic_cids ?? []) {\n if (this._topicOwnsE2eeGroup(topicCid)) {\n this.leaveGroup(topicCid, eventCreatedAt);\n }\n }\n } else if (rejectData.mls_enabled) {\n await this.queuePendingEviction(eventGroupId, rejectedUserId);\n for (const topicCid of rejectData.topic_cids ?? []) {\n if (this._topicOwnsE2eeGroup(topicCid)) {\n await this.queuePendingEviction(topicCid, rejectedUserId);\n }\n }\n }\n break;\n }\n case 'invite_accepted':\n case 'invite_messaging_rejected':\n case 'invite_messaging_skipped':\n break;\n case 'member_removed': {\n const removeData = event.data || {};\n const removedUserId = removeData.member?.user_id;\n const actorUserId = removeData.user?.id;\n if (!removedUserId) {\n markEventSafe();\n continue;\n }\n\n // Keep active channel member state in sync when offline catch-up includes\n // a member removal metadata event from event:{cid}.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventGroupId = this._resolveChannelE2eeGroupId(routeCid, this._getActiveChannel(routeCid));\n const activeChannel = this._getActiveChannel(routeCid) || this._getActiveChannel(eventGroupId);\n if (activeChannel?.state?.members) {\n delete activeChannel.state.members[removedUserId];\n }\n\n if (removedUserId === this.userId) {\n this.leaveGroup(eventGroupId, eventCreatedAt);\n for (const topicCid of removeData.topic_cids ?? []) {\n if (this._topicOwnsE2eeGroup(topicCid)) {\n this.leaveGroup(topicCid, eventCreatedAt);\n }\n }\n markEventSafe();\n continue;\n }\n\n const selfRemoveEvent =\n removeData.self_remove === true ||\n (removeData.self_remove === undefined && !!actorUserId && removedUserId === actorUserId);\n if (!selfRemoveEvent) {\n markEventSafe();\n continue;\n }\n if (!activeChannel || !this.isDesignatedEvictor(activeChannel)) {\n markEventSafe();\n continue;\n }\n\n const group = this.groups.get(eventGroupId);\n if (group) {\n try {\n const leafNodes = group.members_by_user_id(removedUserId);\n if (leafNodes && leafNodes.length > 0) {\n const queue = this._pendingEvictions.get(eventGroupId) ?? new Set<string>();\n queue.add(removedUserId);\n this._pendingEvictions.set(eventGroupId, queue);\n await this._persistPendingEvictions();\n sdkLog(\n 'info',\n '[Encryption] Queued eviction from member_removed sync for',\n removedUserId,\n 'in',\n eventGroupId,\n );\n }\n } catch (_err) {\n // members_by_user_id may fail if group is in invalid state — safe to ignore\n }\n }\n break;\n }\n case 'reaction': {\n // Reaction metadata event — update reaction state for the target message\n const reactionData = event.data;\n const messageId = reactionData?.message_id;\n if (!messageId) {\n markEventSafe();\n continue;\n }\n\n // 1. Update in-memory channel state (if channel is active and has the message)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannel = (this.client as any)?.activeChannels?.[routeCid];\n if (activeChannel?.state?.messageSets) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n activeChannel.state.messageSets.forEach((messageSet: any) => {\n for (let i = 0; i < messageSet.messages.length; i++) {\n if (messageSet.messages[i].id === messageId) {\n messageSet.messages[i] = {\n ...messageSet.messages[i],\n latest_reactions: reactionData.latest_reactions ?? messageSet.messages[i].latest_reactions,\n reaction_counts: reactionData.reaction_counts ?? messageSet.messages[i].reaction_counts,\n };\n break;\n }\n }\n });\n }\n\n // 2. Update local storage — merge reaction fields only\n try {\n const existingMsg = await this.storage.loadE2eeMessage(messageId);\n if (existingMsg) {\n await this.storage.saveE2eeMessage({\n ...existingMsg,\n latest_reactions: reactionData.latest_reactions ?? existingMsg.latest_reactions,\n reaction_counts: reactionData.reaction_counts ?? existingMsg.reaction_counts,\n });\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to update reactions in storage:', messageId, err);\n }\n break;\n }\n case 'message_deleted': {\n // Message deleted event from offline sync — remove message from local state\n const deleteData = event.data;\n const deletedMessageId = deleteData?.message_id;\n if (!deletedMessageId) {\n markEventSafe();\n continue;\n }\n\n // 1. Remove from in-memory channel state\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannel = (this.client as any)?.activeChannels?.[routeCid];\n if (activeChannel?.state) {\n activeChannel.state.removeMessage({ id: deletedMessageId });\n // Also remove from pinned messages if applicable\n activeChannel.state.removePinnedMessage({ id: deletedMessageId });\n }\n\n // 2. Remove from local IndexedDB storage\n try {\n await this.storage.deleteE2eeMessage(deletedMessageId);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to delete message from storage during sync:', deletedMessageId, err);\n }\n\n // 3. Dispatch event for UI re-render\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'message.deleted' as any,\n message: { id: deletedMessageId },\n cid: routeCid,\n });\n\n sdkLog('info', '[Encryption] Sync: message deleted:', deletedMessageId);\n break;\n }\n case 'message_updated': {\n // Message updated event from offline sync. E2EE updates carry the latest\n // encrypted snapshot for the same message id.\n const updateData = event.data;\n const updatedMessage = updateData?.message;\n if (!updatedMessage) {\n markEventSafe();\n continue;\n }\n\n let messageForState = updatedMessage;\n let updateBuffered = false;\n\n try {\n if (updatedMessage.content_type === 'mls' && updatedMessage.mls_ciphertext) {\n const versionedMessage = {\n ...updatedMessage,\n updated_at: updatedMessage.updated_at || updateData.created_at,\n };\n const groupCid = this._resolveMessageE2eeGroupId(versionedMessage, scopeCid);\n const { decrypted, buffered } = await this.decryptApplicationMessages(\n routeCid,\n [versionedMessage],\n groupCid,\n );\n if (buffered.length > 0) {\n updateBuffered = true;\n pendingEncryptionMessages.push(\n ...buffered.map((bufferedMessage: any) =>\n this._toPendingSnapshot(\n routeCid,\n 'message_updated',\n bufferedMessage,\n eventCursor.created_at,\n eventCreatedAt,\n ),\n ),\n );\n await savePendingByRouteCid();\n }\n if (decrypted[0]) {\n messageForState = await this._buildFullMessageWithQuoted(decrypted[0], updatedMessage);\n }\n } else {\n const existingMsg = await this.storage.loadE2eeMessage(updatedMessage.id);\n if (existingMsg) {\n await this.storage.saveE2eeMessage({\n ...existingMsg,\n text: updatedMessage.text ?? existingMsg.text,\n updated_at: updateData.created_at,\n });\n }\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to update message in storage during sync:', updatedMessage.id, err);\n }\n\n if (updateBuffered) {\n sdkLog('info', '[Encryption] Sync: buffered message update:', updatedMessage.id);\n processedEvents += 1;\n lastSafeEventCursor = eventCursor;\n continue;\n }\n\n // 1. Update in-memory channel state\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannel = (this.client as any)?.activeChannels?.[routeCid];\n if (activeChannel?.state) {\n activeChannel.state.addMessageSorted(messageForState, false, false);\n }\n\n // 3. Dispatch event for UI re-render\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'message.updated' as any,\n message: messageForState,\n cid: routeCid,\n });\n\n sdkLog('info', '[Encryption] Sync: message updated:', updatedMessage.id);\n break;\n }\n case 'message_pin': {\n // Pin/unpin event from offline sync — update pinned messages list\n const pinData = event.data;\n const pinnedMessage = pinData?.message;\n if (!pinnedMessage) {\n markEventSafe();\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannel = (this.client as any)?.activeChannels?.[routeCid];\n if (activeChannel?.state) {\n if (pinData.action === 'message.pinned') {\n activeChannel.state.addPinnedMessage(pinnedMessage);\n } else {\n activeChannel.state.removePinnedMessage(pinnedMessage);\n }\n }\n\n sdkLog('info', '[Encryption] Sync: message', pinData.action, ':', pinnedMessage.id);\n break;\n }\n default:\n break;\n }\n\n markEventSafe();\n }\n\n if (pendingEncryptionMessages.length > 0) {\n await retryPendingMessages();\n if (pendingEncryptionMessages.length === 0 && events.length > 0) {\n lastSafeEventCursor = this._eventCursorFromEnvelope(events[events.length - 1], lastSafeEventCursor.created_at);\n }\n }\n\n this._publishDecryptedMessages(decryptedMessages);\n\n sdkLog('info', '[Encryption] Processed', events.length, 'events for:', cid);\n return {\n processedEventCursor: lastSafeEventCursor,\n processedEvents,\n bufferedMessages: pendingEncryptionMessages.length,\n decrypted: decryptedMessages,\n maxObservedEpoch,\n };\n }\n\n private async _syncChannelFromCursor(cid: string, since: EventCursor, limit = 100): Promise<E2eeSyncState> {\n let cursor = since;\n let finalState = this._makeSyncState(cid, 'ready', since, since);\n\n while (true) {\n const startedCursor = cursor;\n const response = await this.e2eeClient!.scopeSync({ [cid]: startedCursor }, limit);\n const result = response.channels?.[cid];\n\n if (!result?.events || result.events.length === 0) {\n const flushed = await this._flushPendingSnapshotsForScope(cid);\n finalState = this._makeSyncState(\n cid,\n result?.has_more ? 'needs_retry' : 'ready',\n startedCursor,\n startedCursor,\n {\n server_next_cursor: result?.next_cursor?.created_at,\n server_next_event_cursor: result?.next_cursor,\n has_more: !!result?.has_more,\n needs_retry: !!result?.has_more,\n buffered_messages: flushed.pending.length,\n },\n );\n this._emitSyncState(finalState);\n return finalState;\n }\n\n const processResult = await this._processChannelEvents(cid, result.events, startedCursor);\n const fallbackNextCursor = this._eventCursorFromEnvelope(\n result.events[result.events.length - 1],\n startedCursor.created_at,\n );\n const serverNextCursor = result.next_cursor ?? fallbackNextCursor;\n const { processedEventCursor, cursorLagged, durableCursor } = this._resolveProcessedEventCursor(\n processResult,\n startedCursor,\n serverNextCursor,\n );\n const processedCursor = processedEventCursor.created_at;\n const blocked = cursorLagged;\n\n finalState = this._makeSyncState(\n cid,\n blocked ? 'needs_retry' : result.has_more ? 'syncing' : 'ready',\n startedCursor,\n processedEventCursor,\n {\n server_next_cursor: serverNextCursor.created_at,\n server_next_event_cursor: serverNextCursor,\n has_more: !!result.has_more,\n needs_retry: !!result.has_more || blocked,\n processed_events: processResult.processedEvents,\n buffered_messages: processResult.bufferedMessages,\n max_observed_epoch: processResult.maxObservedEpoch,\n },\n );\n this._emitSyncState(finalState);\n\n if (compareEventCursor(durableCursor, startedCursor) > 0) {\n cursor = durableCursor;\n await this._saveEncryptionSyncCheckpoint({ scopeCursors: { [cid]: durableCursor } });\n }\n\n if (blocked || !result.has_more) {\n return finalState;\n }\n }\n\n if (this._pendingEvictions.size > 0) {\n await this._persistPendingEvictions();\n }\n }\n\n /**\n * Sync a new E2EE channel that doesn't have a local group yet.\n * Uses scope sync with a single scope cursor.\n */\n async syncNewChannel(channelType: string, channelId: string, cid: string): Promise<EnsureE2eeChannelResult> {\n if (this.groups.has(cid)) {\n return { cid, status: 'ready', epoch: this.getEpoch(cid), sync_state: this.getSyncState(cid) || undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n const savedCursor = await this._loadScopeSyncCursor(cid);\n const since = this._membershipBoundedEventCursor(channel, savedCursor);\n\n const syncState = await this._syncChannelFromCursor(cid, since, 100);\n\n if (!this.groups.has(cid)) {\n // Multi-device fallback: no welcome found (consumed by another device) → external join\n sdkLog('info', '[Encryption] No welcome found for:', cid, '→ attempting external join');\n try {\n const joinResult = await this.joinExternal(channelType, channelId, cid);\n const postJoinState = await this.syncAfterExternalJoin(channelType, channelId, cid);\n sdkLog('info', '[Encryption] External join fallback succeeded:', cid);\n return {\n cid,\n status: postJoinState.status === 'needs_retry' ? 'needs_retry' : 'joined_external',\n epoch: joinResult.epoch,\n sync_state: postJoinState.sync_state,\n };\n } catch (err) {\n sdkLog('warn', '[Encryption] External join fallback failed:', cid, err);\n if ((err as any)?.code === 'stale_group_info') {\n const state = this._makeSyncState(cid, 'stale_group_info', since.created_at, syncState.processed_cursor, {\n needs_retry: true,\n error: (err as Error).message,\n });\n this._emitSyncState(state);\n return { cid, status: 'stale_group_info', sync_state: state, error: (err as Error).message };\n }\n return { cid, status: 'failed', sync_state: syncState, error: (err as Error).message };\n }\n }\n\n return {\n cid,\n status: syncState.needs_retry ? 'needs_retry' : 'joined_welcome',\n epoch: this.getEpoch(cid),\n sync_state: syncState,\n };\n }\n\n /**\n * Sync encryption events for a channel that was just joined via external commit.\n *\n * Unlike syncNewChannel, this method does NOT have the early-return guard\n * (`if (this.groups.has(cid)) return`) so it works correctly when called\n * immediately after joinExternal (when the group IS already in `this.groups`).\n *\n * After decrypting buffered messages it dispatches `e2ee.post_join_sync` on\n * the client so the UI layer can refresh the message list.\n */\n async syncAfterExternalJoin(channelType: string, channelId: string, cid: string): Promise<EnsureE2eeChannelResult> {\n void channelType;\n void channelId;\n if (!this.groups.has(cid)) {\n sdkLog('warn', '[Encryption] syncAfterExternalJoin: no group for', cid, '— skipping');\n return { cid, status: 'skipped', error: 'no local encryption group' };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n const savedCursor = await this._loadScopeSyncCursor(cid);\n const since = this._membershipBoundedEventCursor(channel, savedCursor);\n\n const syncState = await this._syncChannelFromCursor(cid, since, 100);\n\n // Notify UI: E2EE messages for this channel have been decrypted, please refresh.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({ type: 'e2ee.post_join_sync', cid });\n sdkLog('info', '[Encryption] syncAfterExternalJoin complete for:', cid);\n return {\n cid,\n status: syncState.needs_retry ? 'needs_retry' : 'ready',\n epoch: this.getEpoch(cid),\n sync_state: syncState,\n };\n }\n\n async ensureChannelReady(\n channelType: string,\n channelId: string,\n cid: string,\n _options: { source?: 'startup' | 'reconnect' | 'channel_updated' | 'invite_accepted' | 'open' | string } = {},\n ): Promise<EnsureE2eeChannelResult> {\n const source = _options.source;\n if (!this.initialized) {\n return { cid, status: 'failed', error: '[Encryption] Not initialized' };\n }\n\n if (source === 'open' && (await this._isScopeReadyForOpen(cid))) {\n await this._flushPendingSnapshotsForScope(cid);\n return { cid, status: 'ready', epoch: this.getEpoch(cid), sync_state: this.getSyncState(cid) || undefined };\n }\n\n const existing = this._channelReadyLocks.get(cid);\n if (existing) return existing;\n\n const work = (async (): Promise<EnsureE2eeChannelResult> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n if (channel && !this._isE2eeChannelData(channel.data || channel)) {\n return { cid, status: 'skipped', error: 'channel is not E2EE enabled' };\n }\n\n const e2eeGroupId = this._resolveChannelE2eeGroupId(cid, channel);\n if (e2eeGroupId !== cid) {\n const groupParts = channelPartsFromCid(e2eeGroupId);\n if (!groupParts) {\n return { cid, status: 'failed', error: `invalid e2ee_group_id: ${e2eeGroupId}` };\n }\n const result = await this.ensureChannelReady(groupParts.channelType, groupParts.channelId, e2eeGroupId, {\n source: _options.source || 'inherited_topic',\n });\n return {\n cid,\n status: result.status,\n epoch: this.getEpoch(e2eeGroupId),\n sync_state: result.sync_state,\n error: result.error,\n };\n }\n\n if (!this.groups.has(cid)) {\n const result = await this.syncNewChannel(channelType, channelId, cid);\n if (\n result.sync_state &&\n !result.sync_state.needs_retry &&\n result.status !== 'failed' &&\n result.status !== 'stale_group_info'\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.channel_ready',\n cid,\n sync_state: result.sync_state,\n } as any);\n }\n return result;\n }\n\n // Local group exists, but the cursor can still be behind. Run a bounded\n // catch-up sync and let the returned state tell UI whether another retry\n // is needed.\n const savedCursorRecord = await this._loadScopeSyncCursor(cid);\n const memberCreatedAt = this._getMembershipCreatedAt(channel);\n const membershipCursor = memberCreatedAt ? this._initialSyncCursor(memberCreatedAt) : undefined;\n const savedCursor = savedCursorRecord?.created_at;\n\n if (\n source === 'invite_accepted' &&\n membershipCursor &&\n (!savedCursor || compareRfc3339Cursor(membershipCursor, savedCursor) > 0)\n ) {\n await this._deleteLocalGroupState(cid);\n const result = await this.syncNewChannel(channelType, channelId, cid);\n if (\n result.sync_state &&\n !result.sync_state.needs_retry &&\n result.status !== 'failed' &&\n result.status !== 'stale_group_info'\n ) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.channel_ready',\n cid,\n sync_state: result.sync_state,\n } as any);\n }\n return result;\n }\n\n if (source === 'open' && (await this._isScopeReadyForOpen(cid, savedCursorRecord, channel))) {\n await this._flushPendingSnapshotsForScope(cid);\n return { cid, status: 'ready', epoch: this.getEpoch(cid), sync_state: this.getSyncState(cid) || undefined };\n }\n\n const since = this._membershipBoundedEventCursor(channel, savedCursorRecord);\n const syncState = await this._syncChannelFromCursor(cid, since, 100);\n const result: EnsureE2eeChannelResult = {\n cid,\n status: syncState.needs_retry ? 'needs_retry' : 'ready',\n epoch: this.getEpoch(cid),\n sync_state: syncState,\n };\n\n if (!syncState.needs_retry) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (this.client as any)?.dispatchEvent?.({\n type: 'e2ee.channel_ready',\n cid,\n sync_state: syncState,\n } as any);\n }\n return result;\n })().finally(() => {\n this._channelReadyLocks.delete(cid);\n });\n\n this._channelReadyLocks.set(cid, work);\n return work;\n }\n\n // ============================================================\n\n /**\n * Get a cached group or null\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getGroup(cid: string): any | null {\n return this.groups.get(cid) || null;\n }\n\n ownsE2eeGroup(cid: string): boolean {\n return this._resolveChannelE2eeGroupId(cid, this._getActiveChannel(cid)) === cid && this.groups.has(cid);\n }\n\n /**\n * Get the current epoch for a channel.\n * Returns -1 if no local group exists.\n */\n getEpoch(cid: string): number {\n const group = this.groups.get(cid);\n return group ? Number(group.epoch()) : -1;\n }\n\n /**\n * Create a new encryption group for a channel\n * @param cid - e.g. \"messaging:channel_abc\"\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createGroup(cid: string): any {\n const group = wasmModule.Group.create_with_cid(this.provider, this.identity, cid);\n this.groups.set(cid, group);\n // Persist group CID marker to storage\n this._saveGroup(cid);\n sdkLog('info', '[Encryption] Group created:', cid);\n return group;\n }\n\n /**\n * Join a group via Welcome message\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async joinGroup(welcomeBytes: Uint8Array, ratchetTreeBytes?: Uint8Array, primaryUserId?: string): Promise<any> {\n const ratchetTree = ratchetTreeBytes ? wasmModule.RatchetTree.from_bytes(new Uint8Array(ratchetTreeBytes)) : null;\n\n const group = wasmModule.Group.join_with_welcome(this.provider, new Uint8Array(welcomeBytes), ratchetTree);\n\n const cid = group.cid();\n\n // Skip if we already have this group (e.g. we're the creator)\n if (this.groups.has(cid)) {\n sdkLog('info', '[Encryption] Already have group, skipping join:', cid);\n group.free();\n return this.groups.get(cid);\n }\n\n this.groups.set(cid, group);\n await this._saveGroup(cid);\n await this._persistProvider();\n await this.safeArchiveCurrentEpochForCid(cid, 'backup', primaryUserId);\n sdkLog('info', '[Encryption] Joined group via Welcome:', cid);\n return group;\n }\n\n private _isMissingKeyPackageError(err: unknown): boolean {\n const message = String((err as Error)?.message || err || '').toLowerCase();\n return message.includes('no matching key package') || message.includes('key package was found');\n }\n\n /**\n * Save group CID marker to storage.\n * Group state lives inside Provider storage, not serialized separately.\n */\n private async _saveGroup(cid: string): Promise<void> {\n try {\n await this.storage.saveGroupState(cid, true);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to save group CID:', cid, err);\n }\n }\n\n // ============================================================\n // Enable E2EE Flow\n // ============================================================\n\n /**\n * Full enable E2EE flow for a channel.\n *\n * @param channelType - e.g. \"messaging\"\n * @param channelId\n * @param cid - e.g. \"messaging:channel_abc\"\n * @param memberUserIds - all member user IDs to add\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async enableE2ee(\n channelType: string,\n channelId: string,\n cid: string,\n memberUserIds: string[],\n recoveryPolicy: E2eeRecoveryPolicy = 'member_assisted',\n ): Promise<any> {\n // 1. Create encryption group\n const group = this.createGroup(cid);\n\n // 2. Fetch key packages for all members via channel-based API\n // Server auto-excludes sender and returns all devices per member.\n const { members } = await this.e2eeClient!.getKeyPackagesByCid(channelType, channelId);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const allKeyPackages: any[] = [];\n for (const member of members) {\n for (const kpData of member.key_packages) {\n const kp = wasmModule.KeyPackage.from_bytes(new Uint8Array(kpData.key_package));\n allKeyPackages.push(kp);\n }\n }\n\n // 3. Add members to group → get commit + welcome\n const commitBundle = group.add_members(this.provider, this.identity, allKeyPackages);\n\n // 4. Export ratchet tree for new members\n const ratchetTree = group.export_ratchet_tree();\n\n // 5. Get group_info from commitBundle (post-commit epoch N+1 state)\n const exportedGIEnable = commitBundle.group_info;\n if (!exportedGIEnable || exportedGIEnable.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] enableE2ee: commitBundle.group_info is empty — cannot proceed');\n }\n\n // 6. Call enable API\n let result;\n try {\n result = await this.e2eeClient!.enableE2ee(channelType, channelId, {\n welcome: commitBundle.welcome,\n ratchet_tree: ratchetTree.to_bytes(),\n // Send current pre-merge epoch. Server will store epoch+1 (post-commit).\n epoch: Number(group.epoch()),\n group_info: exportedGIEnable,\n e2ee_recovery_policy: recoveryPolicy,\n });\n } catch (err) {\n // Server rejected (e.g. concurrent enable, epoch_stale) → clear pending commit\n sdkLog('error', '[Encryption] enableE2ee failed, clearing pending commit:', err);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw err;\n }\n\n // 6. Merge pending commit locally (only after server OK)\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n await this.safeArchiveCurrentEpoch(channelType, channelId);\n\n sdkLog('info', '[Encryption] E2EE enabled for channel:', cid, 'epoch:', Number(group.epoch()));\n return result;\n }\n\n // ============================================================\n // Create E2EE Channel (Optimistic Inclusion)\n // ============================================================\n\n /**\n * Prepare the encryption bundle for creating a new E2EE channel.\n *\n * Creates a new encryption group, adds all target members (Optimistic Inclusion),\n * and returns the welcome + ratchet_tree + group_info bundle.\n * The caller passes this bundle to `channel.create({ mls_enabled: true, ...bundle })`.\n *\n * **Messaging (DM)**: When `channelType === 'messaging'`, the method auto-computes\n * `channelId` and `cid` using `hash_channel_id(projectId, allMemberUserIds)` from\n * the WASM binding. The computed `channel_id` is included in the returned bundle\n * so the caller can pass it in `data.channel_id` for server validation.\n * In this case, `channelId` and `cid` params are ignored (can be null/empty).\n *\n * **Team**: `channelId` and `cid` must be provided by the caller (e.g. UUID).\n *\n * @param channelType - e.g. \"messaging\" or \"team\"\n * @param channelId - new channel ID. Ignored for Messaging (computed from hash).\n * @param cid - e.g. \"team:proj-uuid\". Ignored for Messaging (computed from hash).\n * @param allMemberUserIds - all member user IDs to add (including sender if desired — server KP API auto-excludes sender's KPs)\n */\n async createE2eeChannel(\n channelType: string,\n channelId: string | null,\n cid: string | null,\n allMemberUserIds: string[],\n ): Promise<{\n welcome: Uint8Array;\n ratchet_tree: Uint8Array;\n group_info: Uint8Array;\n epoch: number;\n channel_id?: string;\n cid: string;\n }> {\n // For messaging (DM), compute deterministic channelId from hash_channel_id binding.\n // This ensures the client-generated cid matches what the server will validate.\n if (channelType === 'messaging') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const projectId = (this.client as any)?.projectId;\n if (!projectId)\n throw new Error('[Encryption] createE2eeChannel: client.projectId is required for messaging E2EE');\n channelId = wasmModule.hash_channel_id(projectId, allMemberUserIds);\n cid = `messaging:${channelId}`;\n sdkLog('info', '[Encryption] createE2eeChannel: computed messaging channelId:', channelId);\n }\n\n if (!channelId || !cid) {\n throw new Error('[Encryption] createE2eeChannel: channelId and cid are required for non-messaging channels');\n }\n\n // 1. Create encryption group (solo — just creator, epoch 0)\n const group = this.createGroup(cid);\n\n // 2. Fetch key packages for all members via batch API (no channel needed)\n // Server auto-excludes sender; members without KPs are silently omitted.\n const requestedRecipientIds = Array.from(new Set(allMemberUserIds)).filter((userId) => userId !== this.userId);\n const { members } = await this.e2eeClient!.getKeyPackagesByUserIds(allMemberUserIds);\n const membersWithKeyPackages = new Set(\n members.filter((member) => member.key_packages?.length > 0).map((member) => member.user_id),\n );\n const missingKeyPackageUserIds = requestedRecipientIds.filter((userId) => !membersWithKeyPackages.has(userId));\n\n if (missingKeyPackageUserIds.length > 0) {\n this.groups.delete(cid);\n await this.storage.deleteGroup?.(cid);\n await this._persistProvider();\n throw new Error(\n `[Encryption] Cannot create E2EE channel. The following members have no uploaded KeyPackages: ${missingKeyPackageUserIds.join(\n ', ',\n )}. Ask them to sign in once with E2EE enabled, then try again.`,\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const allKeyPackages: any[] = [];\n for (const member of members) {\n for (const kpData of member.key_packages) {\n const kp = wasmModule.KeyPackage.from_bytes(new Uint8Array(kpData.key_package));\n allKeyPackages.push(kp);\n }\n }\n\n if (allKeyPackages.length === 0 && requestedRecipientIds.length === 0) {\n // Channel has only the creator. Proceed with a solo commit.\n sdkLog('info', '[Encryption] createE2eeChannel: no other member KPs found, creating solo group for:', cid);\n }\n\n // 3. Add members → commit + welcome (or solo commit if no KPs)\n const commitBundle =\n allKeyPackages.length > 0\n ? group.add_members(this.provider, this.identity, allKeyPackages)\n : group.commit_pending_proposals(this.provider, this.identity);\n\n // 4. Export ratchet tree (needed for welcome recipients)\n const ratchetTree = group.export_ratchet_tree();\n\n // 5. Get group_info from commitBundle (post-commit epoch N+1 state)\n const exportedGI = commitBundle.group_info;\n if (!exportedGI || exportedGI.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] createE2eeChannel: commitBundle.group_info is empty — cannot proceed');\n }\n\n // 6. Capture pre-merge epoch\n const premergeEpoch = Number(group.epoch());\n\n // 7. Merge commit locally (group advances to epoch N+1)\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n\n sdkLog('info', '[Encryption] createE2eeChannel: bundle ready for cid:', cid, 'epoch:', Number(group.epoch()));\n\n const result: {\n welcome: Uint8Array;\n ratchet_tree: Uint8Array;\n group_info: Uint8Array;\n epoch: number;\n channel_id?: string;\n cid: string;\n } = {\n welcome: allKeyPackages.length > 0 ? (commitBundle.welcome as Uint8Array) : new Uint8Array(0),\n ratchet_tree: ratchetTree.to_bytes() as Uint8Array,\n group_info: exportedGI as Uint8Array,\n epoch: premergeEpoch,\n cid,\n };\n\n // For messaging, include channel_id so the caller can pass it in data.channel_id\n // for server-side hash validation.\n if (channelType === 'messaging') {\n result.channel_id = channelId;\n }\n\n return result;\n }\n\n // ============================================================\n // Add Members (Batch)\n // ============================================================\n\n /** Ensure the loaded WASM artifact supports composite inline commits. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _requireCompositeCommitMethods(group: any): void {\n const required = ['commit_member_add_with_removals', 'commit_self_update_with_removals', 'commit_member_removals'];\n for (const method of required) {\n if (typeof group?.[method] !== 'function') {\n throw new Error(`[Encryption] OpenMLS WASM is outdated: missing ${method}()`);\n }\n }\n }\n\n /**\n * Collect pending ghost user_ids that still have encryption leaves.\n *\n * The returned list is safe to pass to composite commit wrappers. Stale queue entries that\n * no longer have leaves are removed from local persistence, because they were already evicted\n * by another commit.\n */\n private async _collectPendingGhosts(cid: string, extraRemoveIds: string[] = []): Promise<string[]> {\n const group = this.groups.get(cid);\n if (!group) return [];\n\n const pending = this._pendingEvictions.get(cid);\n const candidates = new Set<string>([...(pending ?? []), ...extraRemoveIds]);\n const ghostsToRemove: string[] = [];\n\n for (const userId of candidates) {\n if (!userId) continue;\n if (this.userId && userId === this.userId) {\n if (pending?.has(userId)) {\n pending.delete(userId);\n await this._removePendingEviction(cid, userId);\n }\n continue;\n }\n\n try {\n const leafNodes = group.members_by_user_id(userId);\n if (leafNodes && leafNodes.length > 0) {\n ghostsToRemove.push(userId);\n } else if (pending?.has(userId)) {\n pending.delete(userId);\n await this._removePendingEviction(cid, userId);\n }\n } catch (_err) {\n // If membership lookup fails, keep the candidate in the queue. The next sync/action can retry.\n }\n }\n\n if (pending && pending.size === 0) this._pendingEvictions.delete(cid);\n return Array.from(new Set(ghostsToRemove));\n }\n\n /**\n * Remove successfully evicted ghosts from the pending queue.\n * Called AFTER server confirms and merge_pending_commit succeeds.\n */\n private async _cleanupEvictedGhosts(cid: string, ghostsEvicted: string[]): Promise<void> {\n if (ghostsEvicted.length === 0) return;\n const pending = this._pendingEvictions.get(cid);\n if (!pending) return;\n for (const userId of ghostsEvicted) {\n pending.delete(userId);\n await this._removePendingEviction(cid, userId);\n }\n if (pending.size === 0) this._pendingEvictions.delete(cid);\n await this._persistPendingEvictions();\n sdkLog('info', '[Encryption] Cleaned up evicted ghosts:', ghostsEvicted, 'from', cid);\n }\n\n private _isActiveChannelMember(cid: string, userId: string): boolean {\n const activeChannel = this._getActiveChannel(cid);\n if (!activeChannel) return false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = activeChannel.data as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const state = activeChannel.state as any;\n const dataMembers = Array.isArray(data?.members) ? data.members : [];\n if (dataMembers.some((m: any) => m?.user_id === userId)) return true;\n return Boolean(state?.members?.[userId]);\n }\n\n /**\n * After a concurrent re-add/epoch race, a pending ghost may become an active\n * member again before our drain-only commit reaches the server. Drop those\n * entries so retry builds a fresh target_user_ids list from current state.\n */\n private async _dropActivePendingEvictions(cid: string, candidates: string[]): Promise<string[]> {\n const dropped: string[] = [];\n const pending = this._pendingEvictions.get(cid);\n for (const userId of new Set(candidates)) {\n if (!this._isActiveChannelMember(cid, userId)) continue;\n if (pending?.has(userId)) {\n pending.delete(userId);\n await this._removePendingEviction(cid, userId);\n }\n dropped.push(userId);\n }\n if (pending && pending.size === 0) this._pendingEvictions.delete(cid);\n if (dropped.length > 0) {\n await this._persistPendingEvictions();\n sdkLog('info', '[Encryption] Dropped pending ghosts that are active again:', dropped, 'from', cid);\n }\n return dropped;\n }\n\n /**\n * Add members to an E2EE channel.\n * If any of the new users are in the pending eviction queue (ghosts),\n * they are evicted first and then re-added in the SAME commit.\n *\n * @param newUserIds - IDs of users to add\n */\n async addMembers(\n channelType: string,\n channelId: string,\n cid: string,\n newUserIds: string[],\n isRetry = false,\n ): Promise<{ epoch: number }> {\n const group = this.groups.get(cid);\n if (!group) throw new Error(`[Encryption] No group for cid: ${cid}`);\n\n // 1. Fetch KPs via channel-based API (single call, sender auto-excluded)\n const { members } = await this.e2eeClient!.getKeyPackagesByUserIds(newUserIds);\n // 2. Flatten and deserialize all KPs\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const allKeyPackages: any[] = [];\n for (const member of members) {\n for (const kpData of member.key_packages) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kp = wasmModule.KeyPackage.from_bytes(new Uint8Array(kpData.key_package));\n allKeyPackages.push({ userId: member.user_id, kp });\n }\n }\n\n if (allKeyPackages.length === 0) {\n throw new Error('[Encryption] No key packages available for any target user');\n }\n\n // 3. Handle ghost re-adds — if a NEW user still has an old leaf, remove that\n // leaf and add the fresh KeyPackage in the same composite commit.\n const ghostReaddIds: string[] = [];\n for (const { userId } of allKeyPackages) {\n try {\n const leafNodes = group.members_by_user_id(userId);\n if (leafNodes && leafNodes.length > 0) {\n ghostReaddIds.push(userId);\n }\n } catch (_err) {\n /* ignore */\n }\n }\n\n // 4. Composite inline commit: pending ghost removals + main add operation.\n this._requireCompositeCommitMethods(group);\n const ghostsToRemove = await this._collectPendingGhosts(cid, ghostReaddIds);\n const kpArray = allKeyPackages.map(({ kp }) => kp);\n const commitBundle = group.commit_member_add_with_removals(this.provider, this.identity, ghostsToRemove, kpArray);\n\n // 4. Export ratchet tree BEFORE merge (need pre-merge state for welcome)\n const ratchetTree = group.export_ratchet_tree();\n\n // 5. Get group_info from commitBundle (post-commit epoch N+1 state)\n const exportedGIAdd = commitBundle.group_info;\n if (!exportedGIAdd || exportedGIAdd.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] addMembers: commitBundle.group_info is empty — cannot proceed');\n }\n\n // 6. Send to server FIRST — only merge if server accepts\n // Uses the channel's addMembersE2ee() which calls the standard edit_channel\n // endpoint with encryption fields + X-Device-ID header.\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n if (!channel) {\n throw new Error(`[Encryption] No active channel found for cid: ${cid}`);\n }\n await channel.addMembersE2ee(newUserIds, {\n commit: commitBundle.commit,\n welcome: commitBundle.welcome,\n ratchet_tree: ratchetTree.to_bytes(),\n epoch: Number(group.epoch()),\n group_info: exportedGIAdd,\n });\n } catch (err) {\n if (isEpochStaleError(err) && !isRetry) {\n sdkLog('warn', '[Encryption] addMembers: epoch_stale, clearing + syncing + retrying');\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n await this.sync();\n return this.addMembers(channelType, channelId, cid, newUserIds, true);\n }\n // Any other error → clear pending commit + rethrow\n sdkLog('error', '[Encryption] addMembers failed, clearing pending commit:', err);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw err;\n }\n\n // Server OK → merge pending commit locally\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n await this.safeArchiveCurrentEpoch(channelType, channelId);\n await this._cleanupEvictedGhosts(cid, ghostsToRemove);\n\n sdkLog('info', '[Encryption] Added', newUserIds.length, 'users to:', cid, 'epoch:', Number(group.epoch()));\n return { epoch: Number(group.epoch()) };\n }\n\n // ============================================================\n /**\n * Drain the deferred eviction queue built during sync.\n * Runs after the sync loop so epoch is fully up-to-date before we commit.\n *\n * Retry strategy:\n * - `epoch_stale`: handled automatically inside `evictMember` (clear + sync + retry once)\n * - Other failures: logged and skipped — next reconnect sync will re-queue from SystemMessage\n */\n private async _drainPendingEvictions(): Promise<void> {\n if (this._pendingEvictions.size === 0) return;\n\n const pendingEvictions = new Map(this._pendingEvictions);\n\n for (const [cid, userIds] of pendingEvictions) {\n const colonIdx = cid.indexOf(':');\n const channelType = cid.substring(0, colonIdx);\n const channelId = cid.substring(colonIdx + 1);\n const group = this.groups.get(cid);\n const activeChannel = this._getActiveChannel(cid);\n\n if (!activeChannel) {\n continue;\n }\n\n if (!this.isDesignatedEvictor(activeChannel)) {\n sdkLog(\n 'info',\n '[Encryption] _drainPendingEvictions: keep queued for',\n cid,\n '— this client is not designated evictor',\n );\n continue;\n }\n\n if (!group) continue;\n\n const ghostsToRemove = await this._collectPendingGhosts(cid, Array.from(userIds));\n if (ghostsToRemove.length === 0) continue;\n\n try {\n this._requireCompositeCommitMethods(group);\n const commitBundle = group.commit_member_removals(this.provider, this.identity, ghostsToRemove);\n const groupInfoBytes = commitBundle.group_info;\n if (!groupInfoBytes || groupInfoBytes.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] _drainPendingEvictions: commitBundle.group_info is empty');\n }\n\n await this.e2eeClient!.commitEviction(channelType, channelId, {\n target_user_ids: ghostsToRemove,\n commit: commitBundle.commit,\n epoch: Number(group.epoch()),\n group_info: groupInfoBytes,\n });\n\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n await this._cleanupEvictedGhosts(cid, ghostsToRemove);\n } catch (err) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n const activeTarget = getActiveTargetFromCommitEvictionError(err);\n if (activeTarget) {\n await this.sync();\n await this._dropActivePendingEvictions(cid, [activeTarget]);\n sdkLog(\n 'warn',\n '[Encryption] _drainPendingEvictions: target active again, dropped from retry list:',\n cid,\n activeTarget,\n );\n continue;\n }\n if (isEpochStaleError(err)) {\n await this.sync();\n await this._dropActivePendingEvictions(cid, ghostsToRemove);\n }\n sdkLog('warn', '[Encryption] _drainPendingEvictions: composite commit failed, queue kept for retry:', cid, err);\n }\n }\n }\n\n /** Snapshot current queue and write to IndexedDB. */\n private async _persistPendingEvictions(): Promise<void> {\n const pendingEvictions: Record<string, string[]> = {};\n for (const [cid, userIds] of this._pendingEvictions) {\n pendingEvictions[cid] = Array.from(userIds);\n }\n await this.storage.savePendingEvictions(pendingEvictions);\n }\n\n /** Remove a single user from persisted pending evictions after successful eviction. */\n private async _removePendingEviction(cid: string, userId: string): Promise<void> {\n const current = await this.storage.loadPendingEvictions();\n const users = new Set(current[cid] ?? []);\n users.delete(userId);\n if (users.size === 0) {\n delete current[cid];\n } else {\n current[cid] = Array.from(users);\n }\n await this.storage.savePendingEvictions(current);\n }\n\n // Self-Leave & Orphaned Group Cleanup\n // ============================================================\n\n private async _deleteLocalGroupState(cid: string): Promise<void> {\n const group = this.groups.get(cid);\n if (group) {\n try {\n if (typeof group.delete_state === 'function') {\n group.delete_state(this.provider);\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] _deleteLocalGroupState: failed to delete OpenMLS group state for', cid, err);\n }\n this.groups.delete(cid);\n sdkLog('info', '[Encryption] _deleteLocalGroupState: deleted local group state for', cid);\n }\n\n this._channelReadyUntil.delete(cid);\n await this.storage.deleteGroup?.(cid);\n await this._savePendingSnapshots(cid, []);\n await this._persistProvider();\n }\n\n /**\n * Cleanup local encryption group state after self-leave.\n * Called by channel.ts `member.removed` handler when the removed user is self.\n */\n leaveGroup(cid: string, removedAt?: string | number | Date): void {\n const removedCursor = this._toCursorString(removedAt);\n const group = this.groups.get(cid);\n if (group) {\n try {\n if (typeof group.delete_state === 'function') {\n group.delete_state(this.provider);\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] leaveGroup: failed to delete OpenMLS group state for', cid, err);\n }\n this.groups.delete(cid);\n sdkLog('info', '[Encryption] leaveGroup: deleted local group state for', cid);\n }\n // Fire-and-forget: remove the local group marker and move the per-cid cursor\n // past the removal event. Without this, a later re-add can replay an old\n // already-consumed Welcome and fail with \"No matching key package\".\n this._persistProvider().catch((err) => sdkLog('warn', err));\n this.storage.deleteGroup?.(cid).catch?.((err) => sdkLog('warn', err));\n this._saveScopeSyncCursor(cid, { created_at: removedCursor, event_id: ZERO_EVENT_ID }).catch((err) =>\n sdkLog('warn', err),\n );\n this._savePendingSnapshots(cid, []).catch((err) => sdkLog('warn', err));\n }\n\n /**\n * Remove local groups for channels no longer in the server channel list.\n * Called after fetching channels on init/reconnect (handles C3-offline scenario:\n * device was offline when user left, now online → channel not in list → cleanup).\n *\n * @param activeChannelCids - Array of CIDs currently returned by server\n */\n async cleanupOrphanedGroups(activeChannelCids: string[]): Promise<void> {\n const serverCidSet = new Set(activeChannelCids);\n const orphans: string[] = [];\n for (const [cid] of this.groups) {\n if (!serverCidSet.has(cid)) {\n orphans.push(cid);\n }\n }\n for (const cid of orphans) {\n this.groups.delete(cid);\n await this.storage.deleteGroup?.(cid);\n sdkLog('info', '[Encryption] cleanupOrphanedGroups: removed orphaned group', cid);\n }\n if (orphans.length > 0) {\n await this._persistProvider();\n }\n }\n\n // ============================================================\n // Eviction (Reject / Skip / Self-leave handling)\n // ============================================================\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _getActiveChannel(cid: string): any | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const activeChannels = ((this.client as any)?.activeChannels || {}) as Record<string, any>;\n if (activeChannels[cid]) return activeChannels[cid];\n\n for (const channel of Object.values(activeChannels)) {\n const topic = channel?.state?.topics?.find((candidate: any) => candidate?.cid === cid);\n if (topic) return topic;\n }\n\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _membershipRoleForChannel(channel: any): string | undefined {\n if (!this.userId || !channel) return undefined;\n\n const stateMember = channel.state?.members?.[this.userId];\n if (stateMember?.channel_role) return stateMember.channel_role;\n\n const membership = channel.state?.membership;\n if (membership?.channel_role) return membership.channel_role;\n\n const dataMembers = Array.isArray(channel.data?.members) ? channel.data.members : [];\n const dataMember = dataMembers.find(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (member: any) => member?.user_id === this.userId || member?.user?.id === this.userId,\n );\n return dataMember?.channel_role;\n }\n\n private _isInactiveInviteRole(role?: string): boolean {\n return role === 'pending' || role === 'rejected' || role === 'skipped';\n }\n\n isChannelEncryptionSyncBlocked(cid: string): boolean {\n return this._isInactiveInviteRole(this._membershipRoleForChannel(this._getActiveChannel(cid)));\n }\n\n private _isEncryptionProcessingBlockedForRoute(routeCid: string, groupCid?: string): boolean {\n if (groupCid && groupCid !== routeCid) {\n const routeChannel = this._getActiveChannel(routeCid);\n if (this._resolveChannelE2eeGroupId(routeCid, routeChannel) === groupCid) {\n return this.isChannelEncryptionSyncBlocked(groupCid);\n }\n }\n return (\n this.isChannelEncryptionSyncBlocked(routeCid) ||\n (!!groupCid && groupCid !== routeCid && this.isChannelEncryptionSyncBlocked(groupCid))\n );\n }\n\n private _shouldLogThrottled(map: Map<string, number>, key: string, ttlMs: number): boolean {\n const now = Date.now();\n const last = map.get(key) || 0;\n if (now - last < ttlMs) return false;\n map.set(key, now);\n if (map.size > 2_000) {\n for (const [entryKey, timestamp] of map) {\n if (now - timestamp > ttlMs) map.delete(entryKey);\n }\n }\n return true;\n }\n\n private _logDeferredEncryptionEventOnce(\n reason: string,\n routeCid: string,\n groupCid: string,\n messageId?: string,\n ): void {\n const key = `${reason}:${routeCid}:${groupCid}:${messageId || ''}`;\n if (!this._shouldLogThrottled(this._deferredEncryptionEventLogKeys, key, ENCRYPTION_EXPECTED_DECRYPT_LOG_TTL_MS))\n return;\n sdkLog('info', '[Encryption] Deferred encryption event until channel state is ready:', {\n reason,\n cid: routeCid,\n groupCid,\n messageId,\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _safeGroupEpoch(group: any): number | undefined {\n try {\n const epoch = Number(group?.epoch?.());\n return Number.isFinite(epoch) ? epoch : undefined;\n } catch (_) {\n return undefined;\n }\n }\n\n private _isRecoveryVaultLockedOrUnknown(): boolean {\n return !this._recoveryPrivateKey && this._recoveryVaultKnown !== false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _isExpectedRecoverableDecryptFailure(group: any, message: { mls_epoch?: number }, errMsg: string): boolean {\n const groupEpoch = this._safeGroupEpoch(group);\n const msgEpoch = typeof message.mls_epoch === 'number' ? message.mls_epoch : undefined;\n const historicalByEpoch = groupEpoch !== undefined && msgEpoch !== undefined && msgEpoch <= groupEpoch;\n const recoveryError =\n errMsg.includes('Generation is too old') ||\n errMsg.includes('AEAD decryption') ||\n errMsg.includes('epoch differs from the group');\n\n return (this._isRecoveryVaultLockedOrUnknown() && (historicalByEpoch || recoveryError)) || historicalByEpoch;\n }\n\n private _logExpectedDecryptFailureOnce(\n routeCid: string,\n message: { id: string; mls_epoch?: number; [key: string]: unknown },\n groupEpoch: number | undefined,\n errMsg: string,\n ): void {\n const key = `${routeCid}:${this._messageVersionKey(message)}:${errMsg}`;\n if (!this._shouldLogThrottled(this._expectedDecryptLogKeys, key, ENCRYPTION_EXPECTED_DECRYPT_LOG_TTL_MS)) return;\n sdkLog('info', '[Encryption] Message is waiting for encrypted history recovery:', {\n cid: routeCid,\n msgId: message.id,\n groupEpoch,\n msgEpoch: message.mls_epoch,\n vaultLocked: this._isRecoveryVaultLockedOrUnknown(),\n error: errMsg,\n });\n }\n\n async queuePendingEviction(cid: string, targetUserId: string): Promise<boolean> {\n if (!targetUserId || (this.userId && targetUserId === this.userId)) return false;\n\n const activeChannel = this._getActiveChannel(cid);\n if (!activeChannel || !this.isDesignatedEvictor(activeChannel)) return false;\n\n const group = this.groups.get(cid);\n if (!group) return false;\n\n try {\n const leafNodes = group.members_by_user_id(targetUserId);\n if (!leafNodes || leafNodes.length === 0) return false;\n } catch (_err) {\n return false;\n }\n\n const queue = this._pendingEvictions.get(cid) ?? new Set<string>();\n queue.add(targetUserId);\n this._pendingEvictions.set(cid, queue);\n await this._persistPendingEvictions();\n sdkLog('info', '[Encryption] Queued pending eviction for', targetUserId, 'in', cid);\n return true;\n }\n\n /**\n * Determine if this client is the designated evictor for a given channel.\n * We use a deterministic rule so that exactly ONE online evictor triggers commit:\n * 1. Owner (created_by.id) → evictor when this client is the owner\n * 2. Otherwise → online moder with lexicographically lowest user_id\n *\n * Roles allowed to remove others (server: channel.rs):\n * ChannelRole::Owner | ChannelRole::Moder → can remove any member\n * ChannelRole::Member → self-remove only\n *\n * This prevents the race condition where multiple moders all try to evict simultaneously.\n */\n isDesignatedEvictor(channel: { data?: Record<string, unknown>; state?: Record<string, unknown> }): boolean {\n if (!this.userId) return false;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = channel.data as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const state = channel.state as any;\n\n // Owner is the designated evictor when their own client is online.\n const createdById = data?.created_by?.id || data?.channel?.created_by?.id;\n if (createdById && createdById === this.userId) return true;\n\n const onlineIds = new Set<string>(Object.keys(state?.watchers || {}));\n onlineIds.add(this.userId);\n if (createdById && onlineIds.has(createdById)) return false;\n\n // Among online moders (ChannelRole::Moder on server), pick the lowest-sorted\n // user_id. Members are not designated commit_eviction callers.\n const stateMembers = state?.members ? Object.values(state.members) : [];\n const members: Array<{ user_id?: string; channel_role?: string }> =\n Array.isArray(data?.members) && data.members.length > 0 ? data.members : (stateMembers as any);\n const eligibleIds = members\n .filter((m) => (m.channel_role || '') === 'moder')\n .map((m) => m.user_id)\n .filter((id): id is string => Boolean(id && onlineIds.has(id)))\n .sort();\n return eligibleIds.length > 0 && eligibleIds[0] === this.userId;\n }\n\n /**\n * Remove a member from the encryption group.\n *\n * @param channelType - e.g. \"team\"\n * @param channelId - channel ID\n * @param cid - full CID e.g. \"team:xxx:yyy\"\n * @param targetUserId - user to evict\n * @param selfLeft - true → target already self-left (use POST /commit_eviction; no DB check)\n * false → admin kick (use edit_channel; removes from channel DB + encryption)\n * @param isRetry - internal: true on second attempt after epoch_stale\n */\n async evictMember(\n channelType: string,\n channelId: string,\n cid: string,\n targetUserId: string,\n selfLeft = false,\n isRetry = false,\n ): Promise<void> {\n if (!this.provider || !this.identity || !this.client || !this.storage || !this.e2eeClient) {\n throw new Error('[Encryption] Not initialized');\n }\n if (!selfLeft && this.userId && targetUserId === this.userId) {\n throw new Error(\n '[Encryption] evictMember cannot remove the current user; use channel.leaveChannelE2ee() for self-leave',\n );\n }\n\n const group = this.groups.get(cid);\n if (!group) {\n sdkLog('warn', '[Encryption] evictMember: no local group for', cid, '— skipping');\n return;\n }\n\n sdkLog('info', '[Encryption] Evicting member:', targetUserId, 'from:', cid, '(selfLeft:', selfLeft, ')');\n\n let targetHasLeaf = true;\n try {\n const targetLeaves = group.members_by_user_id(targetUserId);\n targetHasLeaf = Boolean(targetLeaves && targetLeaves.length > 0);\n } catch (_err) {\n // Let WASM surface the authoritative error below.\n }\n\n // 1. Collect target + pending ghosts and remove them in ONE inline commit.\n const allRemoveIds = await this._collectPendingGhosts(cid, [targetUserId]);\n if (!targetHasLeaf && !selfLeft) {\n throw new Error(`[Encryption] evictMember: target ${targetUserId} has no encryption leaf in ${cid}`);\n }\n if (allRemoveIds.length === 0) {\n if (selfLeft) {\n await this._removePendingEviction(cid, targetUserId);\n return;\n }\n throw new Error(`[Encryption] evictMember: no encryption leaves to remove for ${targetUserId} in ${cid}`);\n }\n if (allRemoveIds.length > 1) {\n sdkLog('info', '[Encryption] evictMember: bundling', allRemoveIds.length - 1, 'ghosts with target eviction');\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let commitBundle: any;\n try {\n this._requireCompositeCommitMethods(group);\n commitBundle = group.commit_member_removals(this.provider, this.identity, allRemoveIds);\n } catch (err) {\n sdkLog('error', '[Encryption] evictMember: WASM commit_member_removals failed:', err);\n throw err;\n }\n\n // 2. Get GroupInfo from commitBundle (must be present — post-commit epoch N+1 state)\n const groupInfoBytes = commitBundle.group_info;\n if (!groupInfoBytes || groupInfoBytes.length === 0) {\n sdkLog('error', '[Encryption] evictMember: commitBundle has no group_info');\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] evictMember: commitBundle.group_info is empty — cannot proceed');\n }\n\n // 3. Send to correct server endpoint based on whether target already left\n try {\n if (selfLeft) {\n // Target already removed from channel DB (self_remove=true).\n // Use dedicated encryption-only endpoint — bypasses membership check.\n if (!this.e2eeClient) throw new Error('[Encryption] e2eeClient not initialized');\n await this.e2eeClient.commitEviction(channelType, channelId, {\n target_user_ids: allRemoveIds,\n commit: commitBundle.commit,\n epoch: Number(group.epoch()),\n group_info: groupInfoBytes,\n });\n } else {\n // Admin kick — target still in channel.\n // edit_channel removes from channel DB AND processes encryption commit atomically.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const channel = (this.client as any)?.activeChannels?.[cid];\n if (!channel) {\n throw new Error(`[Encryption] No active channel found for cid: ${cid}`);\n }\n await channel.removeMembersE2ee([targetUserId], {\n commit: commitBundle.commit,\n epoch: Number(group.epoch()),\n group_info: groupInfoBytes,\n });\n }\n } catch (err) {\n const activeTarget = getActiveTargetFromCommitEvictionError(err);\n if (selfLeft && activeTarget) {\n sdkLog('warn', '[Encryption] evictMember: target active again, dropping pending eviction:', activeTarget);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n await this.sync();\n await this._dropActivePendingEvictions(cid, [activeTarget]);\n return;\n }\n if (isEpochStaleError(err) && !isRetry) {\n // Another commit won the epoch race. Sync first, drop any targets that\n // became active again, then let the remaining queue retry from fresh state.\n sdkLog('warn', '[Encryption] evictMember: epoch_stale — syncing before retry/drop', targetUserId);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n await this.sync();\n if (selfLeft) {\n await this._dropActivePendingEvictions(cid, allRemoveIds);\n }\n return;\n }\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw err;\n }\n\n // 4. Server OK → merge\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n await this.safeArchiveCurrentEpoch(channelType, channelId);\n // 5. Queue cleanup AFTER confirmed merge.\n await this._cleanupEvictedGhosts(cid, allRemoveIds);\n sdkLog('info', '[Encryption] Evicted', targetUserId, 'from:', cid, 'epoch:', Number(group.epoch()));\n }\n\n // ============================================================\n // External Join\n // ============================================================\n\n /**\n * Join an existing E2EE group via External Commit.\n * Use cases: multi-device (same user, new device) or public channel join.\n *\n * Flow: GET GroupInfo → WASM join_external → POST external_join → merge commit\n */\n async joinExternal(\n channelType: string,\n channelId: string,\n cid: string,\n ): Promise<{ epoch: number; status?: E2eeSyncStatus }> {\n if (!this.initialized) throw new Error('[Encryption] Not initialized');\n\n for (let attempt = 0; attempt < 2; attempt++) {\n // 1. Get GroupInfo from server\n const groupInfoResponse = await this.e2eeClient!.getGroupInfo(channelType, channelId);\n if (groupInfoResponse.is_stale) {\n throw staleGroupInfoError(cid);\n }\n\n // 2. WASM: External join → produces group + commit\n const result = wasmModule.Group.join_external(\n this.provider,\n this.identity,\n new Uint8Array(groupInfoResponse.group_info),\n null, // ratchet_tree is included in group_info (with_ratchet_tree=true)\n );\n\n const group = result.group;\n if (!group) throw new Error('[Encryption] External join failed: no group returned');\n\n // 3. Send external join commit to server FIRST.\n // NOTE: group_info CANNOT be inlined here — export_group_info() is only valid\n // AFTER merge_pending_commit(). For external commits, the merged epoch state\n // is required before GroupInfo can be correctly exported.\n try {\n await this.e2eeClient!.externalJoin(channelType, channelId, {\n commit: result.commit,\n // group.epoch() = N+1 (OpenMLS auto-stages the pending commit).\n // Server external_join_handler expects post-merge epoch and handles CAS internally.\n epoch: Number(group.epoch()),\n // No group_info here — will upload separately after merge below.\n });\n } catch (err) {\n sdkLog('error', '[Encryption] External join failed, clearing pending commit:', err);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n if (isEpochStaleError(err) && attempt === 0) {\n continue;\n }\n throw err;\n }\n\n // 4. Server OK → merge pending commit locally\n group.merge_pending_commit(this.provider);\n\n // 5. Cache group + persist\n this.groups.set(cid, group);\n await this._saveGroup(cid);\n await this._persistProvider();\n\n // 6. Upload GroupInfo AFTER merge — this is the only correct timing for external join.\n // The joiner's N+1 state is now fully committed, so export_group_info() is valid.\n await this._uploadGroupInfo(channelType, channelId, group);\n await this.safeArchiveCurrentEpoch(channelType, channelId);\n\n sdkLog('info', '[Encryption] External join completed for:', cid, 'epoch:', Number(group.epoch()));\n return { epoch: Number(group.epoch()), status: 'joined_external' };\n }\n\n throw new Error('[Encryption] External join failed after retry');\n }\n\n /**\n * Key rotation: rotate own key material for forward secrecy.\n *\n * Composite approach:\n * Pending ghost removals and the self-update are encoded in one inline commit,\n * so receivers need only process the commit and the epoch advances by +1.\n *\n * All other members receive the commit(s) via WS and advance their epoch.\n */\n async keyRotation(cid: string, isRetry = false): Promise<{ epoch: number }> {\n if (!this.initialized) throw new Error('[Encryption] Not initialized');\n\n const group = this.groups.get(cid);\n if (!group) throw new Error(`[Encryption] No group for cid: ${cid}`);\n\n // Extract channelType / channelId from cid\n const colonIdx = cid.indexOf(':');\n if (colonIdx < 0) throw new Error(`[Encryption] Invalid cid format: ${cid}`);\n const channelType = cid.substring(0, colonIdx);\n const channelId = cid.substring(colonIdx + 1);\n\n // 1. Composite inline commit: pending ghost removals + self update.\n this._requireCompositeCommitMethods(group);\n const ghostsToRemove = await this._collectPendingGhosts(cid);\n const bundle = group.commit_self_update_with_removals(this.provider, this.identity, ghostsToRemove);\n\n // 3. Get group_info from bundle (post-commit epoch N+1 state)\n const groupInfoBytes = bundle.group_info;\n if (!groupInfoBytes || groupInfoBytes.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] keyRotation: bundle.group_info is empty — cannot proceed');\n }\n const groupInfoForRequest = groupInfoBytes as Uint8Array;\n\n // 4. Send commit to server FIRST\n try {\n await this.e2eeClient!.keyRotation(channelType, channelId, {\n commit: bundle.commit,\n epoch: Number(group.epoch()),\n group_info: groupInfoForRequest,\n });\n } catch (err) {\n if (isEpochStaleError(err) && !isRetry) {\n sdkLog('warn', '[Encryption] keyRotation: epoch_stale, clearing + syncing + retrying');\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n await this.sync();\n return this.keyRotation(cid, true);\n }\n // Any other error → clear pending commit + rethrow\n sdkLog('error', '[Encryption] keyRotation failed, clearing pending commit:', err);\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw err;\n }\n\n // 5. Server OK → merge pending commit locally → advances epoch\n group.merge_pending_commit(this.provider);\n await this._cleanupEvictedGhosts(cid, ghostsToRemove);\n\n // 6. Persist state\n await this._saveGroup(cid);\n await this._persistProvider();\n await this.safeArchiveCurrentEpoch(channelType, channelId);\n\n sdkLog('info', '[Encryption] Key rotation completed for:', cid, 'epoch:', Number(group.epoch()));\n return { epoch: Number(group.epoch()) };\n }\n\n // ============================================================\n // GroupInfo Upload Helper\n // ============================================================\n\n /**\n * Upload GroupInfo via separate API after merge.\n *\n * Used ONLY for externalJoin (no CommitBundle available, must export after merge)\n * and as a recovery fallback for old clients.\n *\n * For all other commit operations (enableE2ee, addMembers, keyRotation,\n * removeMember) use commitBundle.group_info instead — it is generated\n * by OpenMLS for the new epoch (N+1) and can be sent inline with the commit.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private async _uploadGroupInfo(channelType: string, channelId: string, group: any): Promise<void> {\n try {\n const groupInfoBytes = group.export_group_info(this.provider, this.identity, true);\n sdkLog('info', '[Encryption] Exported group_info for:', channelType, channelId, 'epoch:', Number(group.epoch()));\n if (!channelType || !channelId) {\n sdkLog('warn', '[Encryption] Invalid CID format for GroupInfo upload:', channelType, channelId);\n return;\n }\n await this.e2eeClient!.uploadGroupInfo(channelType, channelId, {\n group_info: groupInfoBytes,\n epoch: Number(group.epoch()),\n });\n sdkLog('info', '[Encryption] GroupInfo uploaded for:', channelType, channelId, 'epoch:', Number(group.epoch()));\n } catch (err) {\n // Non-fatal: GroupInfo upload failure shouldn't block the commit flow\n sdkLog('error', '[Encryption] Failed to upload GroupInfo for:', channelType, channelId, err);\n }\n }\n\n // ============================================================\n // Message Encryption/Decryption\n // ============================================================\n\n /**\n * Encrypt a structured payload for an E2EE channel.\n *\n * The payload is JSON-serialized before encryption so that\n * text, attachments, sticker_url, etc. are all inside the\n * opaque ciphertext — matching bellboy's MessageContent::Standard.\n */\n encryptMessage(cid: string, payload: E2eePayload, aad?: Uint8Array): Uint8Array {\n const group = this.groups.get(cid);\n if (!group) throw new Error(`[Encryption] No group for cid: ${cid}`);\n\n const encoder = new TextEncoder();\n const payloadJson = JSON.stringify(payload);\n const plaintext = encoder.encode(payloadJson);\n const ciphertext = aad\n ? group.create_message_with_aad(this.provider, this.identity, plaintext, aad)\n : group.create_message(this.provider, this.identity, plaintext);\n\n // CRITICAL: Persist encryption ratchet state after create_message().\n // create_message() advances the sender's secret tree generation in-memory.\n // Without save_state(), a page reload restores the old generation → sender\n // re-encrypts at already-consumed generations → receiver gets forward\n // secrecy error (\"message already consumed, cannot re-decrypt\").\n try {\n group.save_state(this.provider);\n } catch (e) {\n sdkLog('warn', '[Encryption] Failed to save group state after encrypt:', e);\n }\n\n return ciphertext;\n }\n\n /**\n * Decrypt an incoming E2EE message.\n *\n * Handles both the new structured JSON payload and legacy\n * plain-text format (backward compatible).\n */\n decryptMessage(cid: string, ciphertext: Uint8Array, expectedAad?: Uint8Array): DecryptResult {\n const group = this.groups.get(cid);\n if (!group) throw new Error(`[Encryption] No group for cid: ${cid}`);\n\n // NOTE: No Provider snapshot/rollback for application messages.\n // process_message passes Provider as read-only (as_ref) for PrivateMessage,\n // so the Provider is NOT modified. Group.process_message(&mut self) may\n // advance the decryption ratchet in-memory, but:\n //\n // - SecretReuseError: thrown BEFORE any state mutation → Group is fine\n // - Successful ratchet advancement + decrypt failure: correct encryption behavior\n // (forward secrecy — can't go back)\n //\n // DO NOT reload Group from Provider — this reverts BOTH decryption AND\n // encryption ratchets, causing the other side to miss our next message.\n const processed = group.process_message(this.provider, new Uint8Array(ciphertext));\n const processedAad = processed.aad ? new Uint8Array(processed.aad) : undefined;\n if (expectedAad && !bytesEqual(processedAad, expectedAad)) {\n throw new Error('[Encryption] MLS AAD mismatch');\n }\n\n // CRITICAL: Persist updated ratchet state to Provider storage.\n // process_message advances the decryption ratchet (secret tree) in the\n // Group's in-memory state, but does NOT write it to Provider storage.\n // Without this, a Provider restore (page reload, reconnect) loads stale\n // ratchet state → SecretReuseError for previously-decrypted messages.\n try {\n group.save_state(this.provider);\n } catch (e) {\n sdkLog('warn', '[Encryption] Failed to save group state after decrypt:', e);\n }\n\n const decoder = new TextDecoder();\n const raw = processed.content ? decoder.decode(processed.content) : '';\n\n // Parse structured JSON payload; fall back to plain text for\n // messages encrypted before the structured-payload migration.\n let payload: E2eePayload;\n try {\n const parsed = JSON.parse(raw);\n // Validate: a structured payload MUST have a 'text' field\n if (parsed && typeof parsed === 'object' && typeof parsed.text === 'string') {\n payload = parsed as E2eePayload;\n } else {\n payload = { text: raw };\n }\n } catch {\n // Not JSON → legacy plain-text message\n payload = { text: raw };\n }\n\n sdkLog('info', '[Encryption] Decrypted message:', payload.text);\n return {\n payload,\n messageType: processed.message_type,\n senderIndex: processed.sender_index,\n epoch: Number(processed.epoch),\n aad: processedAad,\n };\n }\n\n // ============================================================\n // Protocol Event Processing\n // ============================================================\n\n /**\n * Process an encryption commit message\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async processCommit(\n cid: string,\n commitBytes: Uint8Array,\n eventEpoch?: number,\n primaryUserId?: string,\n options: { flushPending?: boolean } = {},\n ): Promise<any | null> {\n if (this.isChannelEncryptionSyncBlocked(cid)) {\n this._logDeferredEncryptionEventOnce('pending_invite_commit', cid, cid);\n return null;\n }\n\n const group = this.groups.get(cid);\n if (!group) {\n sdkLog('warn', '[Encryption] processCommit: no group for', cid);\n return null;\n }\n\n // Pre-check: if group epoch already surpassed the commit's epoch,\n // the commit was already applied. Skip process_message entirely —\n // for ExternalCommit, OpenMLS returns AEAD errors (not epoch mismatch)\n // which can corrupt ratchet state.\n if (eventEpoch !== undefined && eventEpoch >= 0) {\n const groupEpoch = Number(group.epoch());\n sdkLog('info', '[Encryption] processCommit: group epoch:', groupEpoch, 'event epoch:', eventEpoch);\n if (groupEpoch >= eventEpoch) {\n sdkLog(\n 'info',\n `[Encryption] processCommit: commit at epoch ${eventEpoch} already applied (group at ${groupEpoch}), skipping:`,\n cid,\n );\n return null;\n }\n }\n\n // Snapshot Provider snapshot before process_message — commits advance\n // the epoch (irreversible). If processing fails mid-way, rollback.\n const snapshot = this.provider.to_bytes();\n\n try {\n const processed = group.process_message(this.provider, new Uint8Array(commitBytes));\n\n sdkLog('info', '[Encryption] Commit processed for:', cid, 'epoch:', Number(group.epoch()));\n await this._persistProvider();\n await this.safeArchiveCurrentEpochForCid(cid, 'backup', primaryUserId);\n\n // Post-commit queue hygiene: remove users that were evicted by this commit.\n // When another admin's commit removes a ghost, our local queue still has\n // the stale entry. Clean it now so we don't attempt a redundant eviction.\n const pending = this._pendingEvictions.get(cid);\n if (pending && pending.size > 0) {\n let cleaned = false;\n for (const uid of [...pending]) {\n try {\n const leaves = group.members_by_user_id(uid);\n if (!leaves || leaves.length === 0) {\n pending.delete(uid);\n cleaned = true;\n }\n } catch (_err) {\n /* ignore */\n }\n }\n if (cleaned) {\n if (pending.size === 0) this._pendingEvictions.delete(cid);\n this._persistPendingEvictions().catch((err) => sdkLog('warn', err));\n }\n }\n\n if (options.flushPending !== false) {\n await this._flushPendingSnapshotsForScope(cid);\n }\n\n return processed;\n } catch (err) {\n const errMsg = (err as Error).message || '';\n if (errMsg.includes('epoch differs')) {\n // Likely a duplicate commit already processed during sync — safe to ignore\n sdkLog('warn', '[Encryption] processCommit: commit already applied (epoch mismatch), skipping:', cid);\n return null;\n }\n\n // Recovery: \"missing proposal\" means the commit references proposals by reference\n // that we never received (legacy bug from propose_*() + commit_pending_proposals()).\n // Do not auto-advance the sync cursor here. Channel Repair can replay first,\n // then offer a user-confirmed local reset if replay keeps failing.\n if (errMsg.includes('missing a proposal')) {\n sdkLog('warn', '[Encryption] processCommit: missing proposal — repair reset required for', cid);\n this.provider = wasmModule.Provider.from_bytes(new Uint8Array(snapshot));\n const missingProposalError = new Error(\n `[Encryption] Missing proposal while processing commit for ${cid}`,\n ) as Error & {\n code?: string;\n };\n missingProposalError.code = 'missing_proposal';\n throw missingProposalError;\n }\n\n // ROLLBACK: restore Provider from snapshot (commits modify Provider via as_mut)\n sdkLog('warn', '[Encryption] processCommit failed, rolling back Provider snapshot:', errMsg);\n this.provider = wasmModule.Provider.from_bytes(new Uint8Array(snapshot));\n throw err;\n }\n }\n\n /**\n * Process an incoming E2EE application message.\n * Decrypts, persists to local storage, and returns a full Message object\n * that can be directly merged into channel messages state.\n *\n * The returned object combines:\n * - Decrypted E2eePayload (MessageContent::Standard) — text, attachments, sticker_url, polls\n * - Envelope metadata from WS event — id, cid, user, created_at, parent_id, etc.\n */\n /**\n * EncryptionPlaintextCache to deduplicate simultaneous decryption requests for the same message\n * (e.g. from WS and Sync arriving at the same time).\n */\n private _decryptPromises = new Map<string, Promise<Record<string, unknown> | null>>();\n\n private _messageVersionKey(message: {\n id: string;\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n [key: string]: unknown;\n }): string {\n const rawVersion = message.updated_at || message.created_at || '';\n const parsedVersion = rawVersion ? new Date(rawVersion).getTime() : Number.NaN;\n const version = Number.isFinite(parsedVersion) ? new Date(parsedVersion).toISOString() : rawVersion;\n return `${message.id}:${version}`;\n }\n\n private _storedMessageCoversVersion(\n stored: E2eeStoredMessage,\n message: { created_at?: string; updated_at?: string; [key: string]: unknown },\n ): boolean {\n const incomingUpdatedAt = message.updated_at;\n if (!incomingUpdatedAt) return true;\n const storedUpdatedAt = stored.updated_at || stored.created_at;\n return new Date(storedUpdatedAt).getTime() >= new Date(incomingUpdatedAt).getTime();\n }\n\n private _messageTypeForPayload(payload: E2eePayload, fallbackType?: unknown): string {\n if (payload.sticker_url) return 'sticker';\n return typeof fallbackType === 'string' && fallbackType ? fallbackType : 'regular';\n }\n\n private _dateishToIso(value: unknown): string | undefined {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value) return value;\n if (typeof value === 'number' && Number.isFinite(value)) return new Date(value).toISOString();\n return undefined;\n }\n\n private _collectActiveChannelEnvelopes(cid: string): Map<string, ActiveMessageEnvelope> {\n const activeChannel = this.client?.activeChannels?.[cid];\n const messageSets = (activeChannel?.state?.messageSets || []) as Array<{ messages?: ActiveMessageEnvelope[] }>;\n const pinnedMessages = (activeChannel?.state?.pinnedMessages || []) as ActiveMessageEnvelope[];\n const messages = [...messageSets.flatMap((set) => set.messages || []), ...pinnedMessages];\n const envelopes = new Map<string, ActiveMessageEnvelope>();\n for (const message of messages) {\n if (message?.id) envelopes.set(message.id, message);\n }\n return envelopes;\n }\n\n private _buildArchiveMessageEnvelope(\n cid: string,\n ciphertext: HistoricalCiphertext,\n activeEnvelope: ActiveMessageEnvelope | undefined,\n archivedMessage: {\n epoch?: bigint;\n generation?: number;\n own_message?: boolean;\n sender_index?: number;\n },\n ): ArchiveMessageEnvelope {\n const fallbackUserId =\n activeEnvelope?.user?.id ||\n activeEnvelope?.user_id ||\n ciphertext.user?.id ||\n ciphertext.user_id ||\n (archivedMessage.own_message ? this.userId || undefined : undefined);\n const fallbackUser =\n pickUserWithDisplayName(\n fallbackUserId,\n activeEnvelope?.user,\n ciphertext.user,\n fallbackUserId ? this.client?.state?.users?.[fallbackUserId] : undefined,\n fallbackUserId === this.userId ? this.client?.user : undefined,\n ) || (fallbackUserId ? { id: fallbackUserId } : undefined);\n const createdAt =\n this._dateishToIso(activeEnvelope?.created_at) ||\n this._dateishToIso(ciphertext.created_at) ||\n new Date().toISOString();\n const updatedAt = this._dateishToIso(activeEnvelope?.updated_at) || this._dateishToIso(ciphertext.updated_at);\n\n return {\n ...(activeEnvelope || {}),\n ...ciphertext,\n id: ciphertext.message_id,\n cid,\n user: fallbackUser,\n user_id: fallbackUserId,\n created_at: createdAt,\n updated_at: updatedAt,\n mls_epoch: ciphertext.mls_epoch,\n mls_ciphertext: new Uint8Array(ciphertext.mls_ciphertext),\n archive_epoch: archivedMessage.epoch !== undefined ? Number(archivedMessage.epoch) : ciphertext.mls_epoch,\n archive_generation: archivedMessage.generation,\n archive_own_message: archivedMessage.own_message,\n archive_sender_index: archivedMessage.sender_index,\n };\n }\n\n private _storedFromPayload(\n cid: string,\n payload: E2eePayload,\n envelope: { id: string; user?: { id: string }; created_at?: string; updated_at?: string; [key: string]: unknown },\n fallback?: E2eeStoredMessage | null,\n ): E2eeStoredMessage {\n const userId = envelope.user?.id || fallback?.user_id || '';\n const stateUser = userId ? this.client?.state?.users?.[userId] : undefined;\n const user = pickUserWithDisplayName(\n userId,\n stateUser,\n envelope.user,\n fallback?.user,\n userId === this.userId ? this.client?.user : undefined,\n );\n return {\n id: envelope.id,\n cid,\n content_type: 'standard',\n text: payload.text,\n attachments: payload.attachments || fallback?.attachments,\n sticker_url: payload.sticker_url || fallback?.sticker_url,\n poll_type: payload.poll_type || fallback?.poll_type,\n poll_choice_counts: payload.poll_choice_counts || fallback?.poll_choice_counts,\n latest_poll_choices: payload.latest_poll_choices || fallback?.latest_poll_choices,\n old_texts: payload.old_texts || fallback?.old_texts,\n is_edited: !!(payload.old_texts?.length || fallback?.old_texts?.length),\n user_id: userId,\n user,\n created_at: fallback?.created_at || envelope.created_at || new Date().toISOString(),\n updated_at: (envelope.updated_at as string | undefined) || envelope.created_at || fallback?.updated_at,\n type: this._messageTypeForPayload(payload, fallback?.type || (envelope as any).type),\n parent_id: (envelope as any).parent_id || fallback?.parent_id,\n quoted_message_id: (envelope as any).quoted_message_id || fallback?.quoted_message_id,\n forward_cid: (envelope as any).forward_cid || (fallback as any)?.forward_cid,\n forward_message_id: (envelope as any).forward_message_id || (fallback as any)?.forward_message_id,\n forward_parent_cid: (envelope as any).forward_parent_cid || (fallback as any)?.forward_parent_cid,\n e2ee_attachment_ids: (envelope as any).e2ee_attachment_ids || (fallback as any)?.e2ee_attachment_ids,\n mentioned_users: (envelope as any).mentioned_users || fallback?.mentioned_users,\n mentioned_all:\n (envelope as any).mentioned_all !== undefined ? (envelope as any).mentioned_all : fallback?.mentioned_all,\n };\n }\n\n private _normalizeQuotedMessagePreview(message: unknown): Record<string, any> | undefined {\n if (!message || typeof message !== 'object') return undefined;\n\n const quoted = message as Record<string, any>;\n if (!quoted.id) return undefined;\n\n const userId = quoted.user_id || quoted.user?.id;\n const stateUser = typeof userId === 'string' && userId ? this.client?.state?.users?.[userId] : undefined;\n\n return {\n ...quoted,\n content_type: quoted.content_type || 'standard',\n type: quoted.type || 'regular',\n user_id: userId || quoted.user_id,\n user: pickUserWithDisplayName(userId, stateUser, quoted.user) || (userId ? { id: userId } : undefined),\n attachments: quoted.attachments || [],\n };\n }\n\n private _isRenderableQuotedMessage(message: Record<string, any> | undefined): boolean {\n if (!message) return false;\n if (typeof message.text === 'string' && message.text.trim()) return true;\n if (Array.isArray(message.attachments) && message.attachments.length > 0) return true;\n if (typeof message.sticker_url === 'string' && message.sticker_url) return true;\n if (message.type === 'sticker') return true;\n return false;\n }\n\n private _findQuotedMessageInActiveChannels(messageId: string): Record<string, any> | undefined {\n const activeChannels = Object.values(this.client?.activeChannels || {});\n\n for (const channel of activeChannels) {\n const state = (channel as any)?.state;\n const messageSets = Array.isArray(state?.messageSets) ? state.messageSets : [];\n\n for (const set of messageSets) {\n const messages = Array.isArray(set?.messages) ? set.messages : [];\n const found = messages.find((message: any) => message?.id === messageId);\n const normalized = this._normalizeQuotedMessagePreview(found);\n if (normalized) return normalized;\n }\n\n const pinnedMessages = Array.isArray(state?.pinnedMessages) ? state.pinnedMessages : [];\n const pinned = pinnedMessages.find((message: any) => message?.id === messageId);\n const normalizedPinned = this._normalizeQuotedMessagePreview(pinned);\n if (normalizedPinned) return normalizedPinned;\n }\n\n return undefined;\n }\n\n private async _resolveQuotedMessagePreview(\n quotedMessageId?: unknown,\n explicitQuotedMessage?: unknown,\n ): Promise<Record<string, any> | undefined> {\n const explicit = this._normalizeQuotedMessagePreview(explicitQuotedMessage);\n if (this._isRenderableQuotedMessage(explicit)) return explicit;\n\n if (typeof quotedMessageId !== 'string' || !quotedMessageId) return explicit;\n\n const active = this._findQuotedMessageInActiveChannels(quotedMessageId);\n if (this._isRenderableQuotedMessage(active)) return active;\n\n try {\n const stored = await this.storage.loadE2eeMessage(quotedMessageId);\n const storedQuotedMessage = this._normalizeQuotedMessagePreview(stored);\n if (this._isRenderableQuotedMessage(storedQuotedMessage)) return storedQuotedMessage;\n return explicit;\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to hydrate quoted message preview:', { quotedMessageId, err });\n return explicit;\n }\n }\n\n private _expectedAadForMessage(\n routeCid: string,\n groupCid: string,\n message: { id: string; [key: string]: unknown },\n ): Uint8Array | undefined {\n const e2eeAttachmentIds = Array.isArray((message as any).e2ee_attachment_ids)\n ? ((message as any).e2ee_attachment_ids as string[])\n : undefined;\n const params = {\n cid: routeCid,\n e2ee_group_id: groupCid,\n message_id: message.id,\n forward_cid:\n typeof (message as any).forward_cid === 'string' ? ((message as any).forward_cid as string) : undefined,\n forward_message_id:\n typeof (message as any).forward_message_id === 'string'\n ? ((message as any).forward_message_id as string)\n : undefined,\n forward_parent_cid:\n typeof (message as any).forward_parent_cid === 'string'\n ? ((message as any).forward_parent_cid as string)\n : undefined,\n e2ee_attachment_ids: e2eeAttachmentIds,\n };\n return hasE2eeAadMetadata(params) ? buildE2eeMessageAadV1(params) : undefined;\n }\n\n private _manifestAttachmentIds(payload: E2eePayload): string[] {\n if (!Array.isArray(payload.attachments)) return [];\n const ids: string[] = [];\n for (const attachment of payload.attachments as unknown[]) {\n if (\n attachment &&\n typeof attachment === 'object' &&\n (attachment as E2eeAttachmentManifest).version === 1 &&\n typeof (attachment as E2eeAttachmentManifest).attachment_id === 'string'\n ) {\n ids.push((attachment as E2eeAttachmentManifest).attachment_id);\n }\n }\n return ids;\n }\n\n private _validateEnvelopeAttachmentIds(message: Record<string, unknown>, payload: E2eePayload): void {\n const envelopeIds = Array.isArray((message as any).e2ee_attachment_ids)\n ? ((message as any).e2ee_attachment_ids as string[])\n : [];\n const manifestIds = this._manifestAttachmentIds(payload);\n const canonicalEnvelope = canonicalAttachmentIds(envelopeIds);\n const canonicalManifest = canonicalAttachmentIds(manifestIds);\n if (canonicalEnvelope.length !== canonicalManifest.length) {\n throw new Error('[Encryption] E2EE attachment manifest/envelope id mismatch');\n }\n for (let i = 0; i < canonicalEnvelope.length; i += 1) {\n if (canonicalEnvelope[i] !== canonicalManifest[i]) {\n throw new Error('[Encryption] E2EE attachment manifest/envelope id mismatch');\n }\n }\n }\n\n async processE2eeMessage(\n cid: string,\n message: {\n id: string;\n mls_ciphertext?: Uint8Array;\n user?: { id: string };\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n e2ee_group_id?: string;\n [key: string]: unknown;\n },\n ): Promise<Record<string, unknown> | null> {\n const versionKey = this._messageVersionKey(message);\n if (this._decryptPromises.has(versionKey)) {\n sdkLog(\n 'info',\n '[Encryption] processE2eeMessage: deduplicating concurrent request via EncryptionPlaintextCache:',\n versionKey,\n );\n return this._decryptPromises.get(versionKey)!;\n }\n\n const promise = this._processE2eeMessageInternal(cid, message);\n this._decryptPromises.set(versionKey, promise);\n\n try {\n return await promise;\n } finally {\n this._decryptPromises.delete(versionKey);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private async _processE2eeMessageInternal(\n cid: string,\n message: {\n id: string;\n mls_ciphertext?: Uint8Array;\n user?: { id: string };\n created_at?: string;\n updated_at?: string;\n mls_epoch?: number;\n e2ee_group_id?: string;\n [key: string]: unknown;\n },\n ): Promise<Record<string, unknown> | null> {\n const ciphertext = message.mls_ciphertext;\n if (!ciphertext) return null;\n const versionKey = this._messageVersionKey(message);\n const routeCid = (typeof message.cid === 'string' && message.cid) || cid;\n const groupCid = this._resolveMessageE2eeGroupId(message, cid);\n\n if (this._isEncryptionProcessingBlockedForRoute(routeCid, groupCid)) {\n await this._rememberPendingE2eeSnapshot(routeCid, message);\n this._logDeferredEncryptionEventOnce('pending_invite_message', routeCid, groupCid, message.id);\n return null;\n }\n\n if (this.isScopeRepairing(groupCid)) {\n sdkLog('info', '[Encryption] processE2eeMessage: repair in progress, waiting for scope:', groupCid, message.id);\n try {\n await this.waitForScopeRepair(groupCid);\n } catch (_) {\n // Repair gate always resolves; fall through if a custom gate rejects.\n }\n const existing = await this.storage.loadE2eeMessage(message.id);\n if (existing && this._storedMessageCoversVersion(existing, message)) {\n this._decryptedMsgIds.add(versionKey);\n await this._clearRepairIssue(routeCid, message);\n return await this._buildFullMessageWithQuoted(existing, message);\n }\n }\n\n // CRITICAL: If encryption sync is in progress (reconnecting from background),\n // do NOT attempt decryption — it would race with the waterfall decrypt\n // and consume ratchet secrets out of order. Instead, WAIT for sync to\n // finish, then check dedup: if sync already decrypted this message, return\n // the cached result; otherwise decrypt normally (message arrived after the\n // sync window).\n if (this._syncing) {\n sdkLog('info', '[Encryption] processE2eeMessage: sync in progress, waiting for completion:', message.id);\n try {\n await this.waitForSync();\n } catch {\n // Sync failed — fall through to normal decrypt\n }\n // Re-check dedup after sync: sync may have already decrypted this message\n if (this._decryptedMsgIds.has(versionKey)) {\n sdkLog('info', '[Encryption] processE2eeMessage: decrypted by sync (post-wait), returning cached:', versionKey);\n const cached = await this.storage.loadE2eeMessage(message.id);\n if (cached && this._storedMessageCoversVersion(cached, message)) {\n await this._clearRepairIssue(routeCid, message);\n return await this._buildFullMessageWithQuoted(cached, message);\n }\n return null;\n }\n const existing = await this.storage.loadE2eeMessage(message.id);\n if (existing && this._storedMessageCoversVersion(existing, message)) {\n this._decryptedMsgIds.add(versionKey);\n await this._clearRepairIssue(routeCid, message);\n return await this._buildFullMessageWithQuoted(existing, message);\n }\n // Message not in sync window — fall through to normal decrypt below\n }\n\n // CRITICAL: Check if already decrypted (sync waterfall may have processed\n // this message before the WS message.new event arrived). encryption forward secrecy\n // deletes ratchet keys after first decrypt — re-decrypting would fail with\n // \"The requested secret was deleted to preserve forward secrecy.\"\n //\n // Two-tier dedup:\n // 1. In-memory Set (instant, no async) — catches the race where waterfall\n // decrypt consumed the ratchet but IndexedDB hasn't flushed yet.\n // 2. IndexedDB lookup — catches messages decrypted in a previous session.\n if (this._decryptedMsgIds.has(versionKey)) {\n sdkLog('info', '[Encryption] processE2eeMessage: already decrypted (in-memory), skipping:', versionKey);\n const cached = await this.storage.loadE2eeMessage(message.id);\n if (cached && this._storedMessageCoversVersion(cached, message)) {\n await this._clearRepairIssue(routeCid, message);\n return await this._buildFullMessageWithQuoted(cached, message);\n }\n // IndexedDB hasn't flushed yet — return null, UI will show \"Encrypted message\"\n // but the plaintext IS saved and will appear on next channel load.\n return null;\n }\n const existing = await this.storage.loadE2eeMessage(message.id);\n if (existing && this._storedMessageCoversVersion(existing, message)) {\n sdkLog('info', '[Encryption] processE2eeMessage: already decrypted (IndexedDB), skipping:', versionKey);\n this._decryptedMsgIds.add(versionKey);\n await this._clearRepairIssue(routeCid, message);\n return await this._buildFullMessageWithQuoted(existing, message);\n }\n\n const group = this.groups.get(groupCid);\n if (!group) {\n await this._rememberPendingE2eeSnapshot(routeCid, message);\n this._logDeferredEncryptionEventOnce('missing_local_group', routeCid, groupCid, message.id);\n await this._recordRepairIssue(routeCid, message, 'missing_local_snapshot', false);\n return null;\n }\n\n sdkLog('info', '[Encryption] processE2eeMessage:', {\n msgId: message.id,\n cid: routeCid,\n groupCid,\n groupEpoch: Number(group.epoch()),\n msgEpoch: message.mls_epoch,\n senderId: message.user?.id,\n });\n\n try {\n // Ensure ciphertext is Uint8Array (WS may deliver as regular array)\n const ctBytes = ciphertext instanceof Uint8Array ? ciphertext : new Uint8Array(ciphertext as any);\n const expectedAad = this._expectedAadForMessage(routeCid, groupCid, message);\n const { payload, messageType } = this.decryptMessage(groupCid, ctBytes, expectedAad);\n this._validateEnvelopeAttachmentIds(message, payload);\n\n // Mark as decrypted IMMEDIATELY after process_message succeeds —\n // before any async IndexedDB writes. This is the in-memory dedup\n // that prevents the race with waterfall decrypt.\n this._decryptedMsgIds.add(versionKey);\n\n if (messageType === 0) {\n const existingMessage = await this.storage.loadE2eeMessage(message.id);\n const storedMsg = this._storedFromPayload(routeCid, payload, message, existingMessage);\n\n await this.storage.saveE2eeMessage(storedMsg);\n await this._clearRepairIssue(routeCid, message);\n\n // CRITICAL: persist snapshot after decrypt — the ratchet key was\n // consumed during process_message. Without persisting, a reload would\n // restore stale state where the key appears consumed but no plaintext\n // exists → all future decrypts from this sender would fail.\n await this._persistProvider();\n\n // Return full Message object for channel state\n return await this._buildFullMessageWithQuoted(storedMsg, message);\n }\n } catch (err) {\n const errMsg = (err as Error).message || '';\n // Forward secrecy error: the ratchet secret for this message's generation\n // was already consumed (e.g. decrypted in a previous session but IndexedDB\n // save didn't complete before tab suspension). This message is lost, but\n // future messages at higher generations will still work — the ratchet has\n // already advanced past this point.\n if (this._isForwardSecrecyConsumedError(errMsg)) {\n sdkLog('warn', '[Encryption] Forward secrecy: message already consumed, cannot re-decrypt:', message.id, {\n groupEpoch: this._safeGroupEpoch(group),\n msgEpoch: message.mls_epoch,\n });\n await this._recordRepairIssue(routeCid, message, 'forward_secrecy_consumed', false);\n // Return null — the message will remain as \"Encrypted message\" in the UI\n // but won't block future decryptions.\n return null;\n }\n\n const groupEpoch = this._safeGroupEpoch(group);\n if (this._isExpectedRecoverableDecryptFailure(group, message, errMsg)) {\n await this._rememberPendingE2eeSnapshot(routeCid, message);\n this._logExpectedDecryptFailureOnce(routeCid, message, groupEpoch, errMsg);\n await this._recordRepairIssue(routeCid, message, 'decrypt_error', false);\n } else {\n // Epoch mismatch or other recoverable error — log and return null.\n // channel.ts will dispatch 'failed' → UI shows \"Encrypted message\".\n await this._rememberPendingE2eeSnapshot(routeCid, message);\n sdkLog('error', '[Encryption] Failed to decrypt message:', routeCid, {\n msgId: message.id,\n groupEpoch,\n msgEpoch: message.mls_epoch,\n error: errMsg,\n });\n await this._recordRepairIssue(routeCid, message, 'decrypt_error');\n }\n }\n\n return null;\n }\n\n private _isForwardSecrecyConsumedError(errMsg: string): boolean {\n return (\n errMsg.includes('forward secrecy') ||\n errMsg.includes('SecretReuseError') ||\n errMsg.includes('requested secret was deleted')\n );\n }\n\n /**\n * Build a full Message object from decrypted E2eeStoredMessage + envelope metadata.\n *\n * The result has `content_type: 'standard'` and contains all Standard fields,\n * so it can be directly merged into channel messages state like a normal message.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private _buildFullMessage(stored: E2eeStoredMessage, envelope: Record<string, any>): Record<string, any> {\n const userId = stored.user_id || (stored.user as any)?.id || envelope.user?.id || envelope.user_id || '';\n const stateUser = userId ? this.client?.state?.users?.[userId] : undefined;\n const user = pickUserWithDisplayName(\n userId,\n stateUser,\n stored.user,\n envelope.user,\n userId === this.userId ? this.client?.user : undefined,\n );\n return {\n // Core identity (from envelope)\n id: stored.id,\n cid: stored.cid,\n user_id: userId,\n user,\n type: stored.type || envelope.type || 'regular',\n created_at: stored.created_at,\n // Decrypted Standard content\n content_type: 'standard',\n text: stored.text,\n attachments: stored.attachments || [],\n sticker_url: stored.sticker_url,\n poll_type: stored.poll_type,\n poll_choice_counts: stored.poll_choice_counts,\n latest_poll_choices: stored.latest_poll_choices,\n old_texts: stored.old_texts,\n is_edited: stored.is_edited,\n // E2EE status (only present during deferred decryption)\n e2ee_status: (stored as any).e2ee_status || null,\n // Envelope metadata (routing + notifications)\n parent_id: stored.parent_id || envelope.parent_id,\n quoted_message_id: stored.quoted_message_id || envelope.quoted_message_id,\n quoted_message: stored.quoted_message || envelope.quoted_message,\n forward_cid: envelope.forward_cid,\n forward_message_id: envelope.forward_message_id,\n forward_parent_cid: envelope.forward_parent_cid,\n e2ee_attachment_ids: envelope.e2ee_attachment_ids || (stored as any).e2ee_attachment_ids,\n mentioned_users: stored.mentioned_users || envelope.mentioned_users,\n mentioned_all: stored.mentioned_all || envelope.mentioned_all,\n // State (from envelope, server-managed)\n latest_reactions: envelope.latest_reactions || [],\n reaction_counts: envelope.reaction_counts,\n pinned_by: envelope.pinned_by,\n pinned_at: envelope.pinned_at,\n updated_at: stored.updated_at || envelope.updated_at,\n };\n }\n\n private async _buildFullMessageWithQuoted(\n stored: E2eeStoredMessage,\n envelope: Record<string, any>,\n ): Promise<Record<string, any>> {\n const message = this._buildFullMessage(stored, envelope);\n\n const quotedMessage = await this._resolveQuotedMessagePreview(message.quoted_message_id, message.quoted_message);\n if (quotedMessage) message.quoted_message = quotedMessage;\n\n return message;\n }\n\n async uploadE2eeAttachments(\n channelType: string,\n channelId: string,\n files: Blob[],\n options: {\n onProgress?: (progress: {\n fileIndex: number;\n phase: 'generating_preview' | 'encrypting' | 'uploading' | 'completing';\n loaded: number;\n total: number;\n percentage: number;\n }) => void;\n displayOverrides?: Map<number, Record<string, unknown>>;\n signal?: AbortSignal;\n } = {},\n ): Promise<{ attachments: E2eeAttachmentManifest[]; e2ee_attachment_ids: string[] }> {\n if (!this.e2eeClient) throw new Error('[Encryption] E2EE client is not initialized');\n const e2eeClient = this.e2eeClient;\n if (files.length === 0) return { attachments: [], e2ee_attachment_ids: [] };\n if (files.length > 10) throw new Error('[Encryption] E2EE messages support at most 10 attachments');\n\n const attachments: E2eeAttachmentManifest[] = [];\n const ids: string[] = [];\n const multipartEnabled = this._e2eeAttachmentMultipartEnabled;\n\n for (let index = 0; index < files.length; index += 1) {\n const file = files[index] as Blob & { name?: string; type?: string };\n const emitProgress = (progress: {\n phase: 'generating_preview' | 'encrypting' | 'uploading' | 'completing';\n loaded: number;\n total: number;\n percentage: number;\n }) => options.onProgress?.({ fileIndex: index, ...progress });\n\n options.onProgress?.({\n fileIndex: index,\n phase: 'generating_preview',\n loaded: 0,\n total: file.size,\n percentage: 0,\n });\n const previewResult = await generateE2eeAttachmentPreview(file);\n const previewBlob = previewResult?.blob;\n const displayOverrides = options.displayOverrides?.get(index) || {};\n emitProgress({\n phase: 'generating_preview',\n loaded: file.size,\n total: file.size,\n percentage: 100,\n });\n\n const originalDisplay = {\n name: file.name,\n mime_type: file.type,\n size: file.size,\n width: previewResult?.originalWidth,\n height: previewResult?.originalHeight,\n duration: previewResult?.duration,\n ...displayOverrides,\n };\n const originalCipherSizeEstimate = estimateE2eeEncryptedAssetSize(file.size);\n\n let previewEncrypted: Awaited<ReturnType<typeof encryptE2eeAsset>> | undefined;\n if (previewBlob) {\n try {\n previewEncrypted = await encryptE2eeAsset(previewBlob, {\n kind: 'preview',\n cryptoProvider: this._attachmentCryptoProvider,\n display: {\n name: file.name ? `${file.name}.preview.jpg` : undefined,\n mime_type: 'image/jpeg',\n size: previewBlob.size,\n preview_of: 'original',\n width: previewResult?.previewWidth,\n height: previewResult?.previewHeight,\n },\n onProgress: emitProgress,\n });\n } catch {\n previewEncrypted = undefined;\n }\n }\n\n type UploadedOriginal = {\n manifestAsset: ReturnType<typeof buildManifestAsset>;\n completeAsset?: NonNullable<CompleteE2eeAttachmentRequest['assets']>[number];\n };\n\n const uploadOriginalAsset = async (initAsset: InitE2eeAttachmentAssetResponse): Promise<UploadedOriginal> => {\n const uploadMode = initAsset.upload_mode || 'single_put';\n if (uploadMode === 'multipart') {\n if (!initAsset.multipart) {\n throw new Error('[Encryption] E2EE attachment multipart init did not include multipart data');\n }\n const uploaded = await encryptAndUploadE2eeAssetMultipart(file, {\n kind: 'original',\n cryptoProvider: this._attachmentCryptoProvider,\n display: originalDisplay,\n multipart: initAsset.multipart,\n uploadConcurrency: this._e2eeAttachmentMultipartUploadConcurrency,\n onProgress: emitProgress,\n signal: options.signal,\n });\n return {\n manifestAsset: buildManifestAsset(initAsset.asset_id, uploaded.encrypted),\n completeAsset: {\n asset_id: initAsset.asset_id,\n multipart: { parts: uploaded.parts },\n },\n };\n }\n\n if (!initAsset.put_url) {\n throw new Error('[Encryption] E2EE attachment init did not return original PUT URL');\n }\n const originalEncrypted = await encryptE2eeAsset(file, {\n kind: 'original',\n cryptoProvider: this._attachmentCryptoProvider,\n display: originalDisplay,\n onProgress: emitProgress,\n });\n await putPresignedObject(initAsset.put_url, originalEncrypted.encryptedBlob, emitProgress, options.signal);\n return { manifestAsset: buildManifestAsset(initAsset.asset_id, originalEncrypted) };\n };\n\n const completeAttachmentWithRetry = async (\n attachmentId: string,\n request: CompleteE2eeAttachmentRequest,\n ): Promise<void> => {\n for (let attempt = 0; attempt < 2; attempt += 1) {\n try {\n await e2eeClient.completeAttachment(channelType, channelId, attachmentId, request);\n return;\n } catch (err) {\n if (isE2eeAttachmentInvalidError(err) || attempt === 1) throw err;\n await delay(500);\n }\n }\n };\n\n const completeOriginalOnly = async () => {\n const init = await e2eeClient.initAttachment(\n channelType,\n channelId,\n {\n idempotency_key: newUuid(this._attachmentCryptoProvider),\n assets: [{ kind: 'original', cipher_size_estimate: originalCipherSizeEstimate }],\n },\n { multipart: multipartEnabled },\n );\n const initAsset = init.assets.find((asset) => asset.kind === 'original');\n if (!initAsset) throw new Error('[Encryption] E2EE attachment init did not return original asset');\n const uploadedOriginal = await uploadOriginalAsset(initAsset);\n emitProgress({\n phase: 'completing',\n loaded: uploadedOriginal.manifestAsset.cipher_size,\n total: uploadedOriginal.manifestAsset.cipher_size,\n percentage: 100,\n });\n const completeRequest: CompleteE2eeAttachmentRequest = {\n completion_lease_id: newUuid(this._attachmentCryptoProvider),\n ...(uploadedOriginal.completeAsset ? { assets: [uploadedOriginal.completeAsset] } : {}),\n };\n await completeAttachmentWithRetry(init.attachment_id, completeRequest);\n return buildAttachmentManifest({\n attachment_id: init.attachment_id,\n assets: [uploadedOriginal.manifestAsset],\n });\n };\n\n if (!previewEncrypted) {\n const manifest = await completeOriginalOnly();\n attachments.push(manifest);\n ids.push(manifest.attachment_id);\n continue;\n }\n\n const init = await e2eeClient.initAttachment(\n channelType,\n channelId,\n {\n idempotency_key: newUuid(this._attachmentCryptoProvider),\n assets: [\n { kind: 'original', cipher_size_estimate: originalCipherSizeEstimate },\n { kind: 'preview', cipher_size_estimate: previewEncrypted.cipher_size },\n ],\n },\n { multipart: multipartEnabled },\n );\n const originalInitAsset = init.assets.find((asset) => asset.kind === 'original');\n const previewInitAsset = init.assets.find((asset) => asset.kind === 'preview');\n if (!originalInitAsset) throw new Error('[Encryption] E2EE attachment init did not return original asset');\n if (!previewInitAsset) throw new Error('[Encryption] E2EE attachment init did not return preview asset');\n if (!previewInitAsset.put_url)\n throw new Error('[Encryption] E2EE attachment init did not return preview PUT URL');\n\n const uploadedOriginal = await uploadOriginalAsset(originalInitAsset);\n try {\n await putPresignedObject(\n previewInitAsset.put_url,\n previewEncrypted.encryptedBlob,\n emitProgress,\n options.signal,\n );\n } catch {\n void e2eeClient.deleteAttachment(channelType, channelId, init.attachment_id).catch(() => undefined);\n const manifest = await completeOriginalOnly();\n attachments.push(manifest);\n ids.push(manifest.attachment_id);\n continue;\n }\n\n const completeTotal = uploadedOriginal.manifestAsset.cipher_size + previewEncrypted.cipher_size;\n emitProgress({\n phase: 'completing',\n loaded: completeTotal,\n total: completeTotal,\n percentage: 100,\n });\n const completeRequest: CompleteE2eeAttachmentRequest = {\n completion_lease_id: newUuid(this._attachmentCryptoProvider),\n ...(uploadedOriginal.completeAsset ? { assets: [uploadedOriginal.completeAsset] } : {}),\n };\n await completeAttachmentWithRetry(init.attachment_id, completeRequest);\n const manifest = buildAttachmentManifest({\n attachment_id: init.attachment_id,\n assets: [uploadedOriginal.manifestAsset, buildManifestAsset(previewInitAsset.asset_id, previewEncrypted)],\n });\n attachments.push(manifest);\n ids.push(init.attachment_id);\n }\n\n return { attachments, e2ee_attachment_ids: ids };\n }\n\n async createE2eeAttachmentStreamUrl(\n channelType: string,\n channelId: string,\n manifest: E2eeAttachmentManifest,\n kind: 'original' | 'preview' = 'original',\n options: E2eeMediaStreamWorkerOptions = {},\n ): Promise<E2eeMediaStreamHandle | null> {\n if (!this.e2eeClient) throw new Error('[Encryption] E2EE client is not initialized');\n return await createE2eeAttachmentStreamUrl({\n ...options,\n channelType,\n channelId,\n manifest,\n kind,\n renewGrant: async () => {\n const asset =\n manifest.assets.find((item) => item.kind === kind) || (kind === 'original' ? manifest.assets[0] : undefined);\n if (!asset) throw new Error('[Encryption] E2EE attachment manifest has no streamable asset');\n return await this.e2eeClient!.downloadAttachmentGrant(\n channelType,\n channelId,\n manifest.attachment_id,\n asset.asset_id,\n );\n },\n });\n }\n\n async downloadE2eeAttachmentAsset(\n channelType: string,\n channelId: string,\n manifest: E2eeAttachmentManifest,\n kind: 'original' | 'preview' = 'original',\n options: { onProgress?: (progress: E2eeAttachmentTransferProgress) => void } = {},\n ): Promise<Blob> {\n if (!this.e2eeClient) throw new Error('[Encryption] E2EE client is not initialized');\n const asset =\n manifest.assets.find((item) => item.kind === kind) || (kind === 'original' ? manifest.assets[0] : undefined);\n if (!asset) throw new Error('[Encryption] E2EE attachment manifest has no assets');\n options.onProgress?.({ phase: 'granting', loaded: 0, total: 1, percentage: 0 });\n const grant = await this.e2eeClient.downloadAttachmentGrant(\n channelType,\n channelId,\n manifest.attachment_id,\n asset.asset_id,\n );\n options.onProgress?.({ phase: 'granting', loaded: 1, total: 1, percentage: 100 });\n const encrypted = await downloadEncryptedAsset(grant.download_url, options.onProgress);\n return await decryptE2eeAsset(encrypted, asset, this._attachmentCryptoProvider, options.onProgress);\n }\n\n async queryE2eeAttachmentMessages(\n channelType: string,\n channelId: string,\n options: QueryE2eeAttachmentsRequest = {},\n ): Promise<{ attachments: any[]; next_cursor?: unknown; has_more: boolean }> {\n if (!this.e2eeClient) throw new Error('[Encryption] E2EE client is not initialized');\n const response = await this.e2eeClient.queryE2eeAttachments(channelType, channelId, options);\n const messageIds = response.attachments.map((item) => item.message_id);\n const storedMessages = this.storage.loadE2eeMessages\n ? await this.storage.loadE2eeMessages(messageIds)\n : new Map<string, E2eeStoredMessage>();\n if (!this.storage.loadE2eeMessages) {\n for (const messageId of messageIds) {\n const stored = await this.storage.loadE2eeMessage(messageId);\n if (stored) storedMessages.set(messageId, stored);\n }\n }\n\n const attachments = response.attachments.map((projection) =>\n this._mapE2eeAttachmentProjectionToDisplayItem(projection, storedMessages.get(projection.message_id)),\n );\n return {\n attachments,\n next_cursor: response.next_cursor,\n has_more: response.has_more,\n };\n }\n\n private _mapE2eeAttachmentProjectionToDisplayItem(\n projection: QueryE2eeAttachmentProjection,\n stored?: E2eeStoredMessage,\n ): Record<string, unknown> {\n const manifests = Array.isArray(stored?.attachments) ? stored?.attachments : [];\n const manifest = manifests.find((attachment): attachment is E2eeAttachmentManifest => {\n return Boolean(\n attachment &&\n typeof attachment === 'object' &&\n (attachment as E2eeAttachmentManifest).version === 1 &&\n (attachment as E2eeAttachmentManifest).attachment_id === projection.attachment_id &&\n Array.isArray((attachment as E2eeAttachmentManifest).assets),\n );\n });\n const projectionOriginal = projection.assets.find((asset) => asset.kind === 'original') || projection.assets[0];\n if (!manifest) {\n return {\n id: projection.attachment_id,\n attachment_type: 'file',\n user_id: projection.created_by_user_id,\n cid: projection.cid,\n url: '',\n thumb_url: '',\n file_name: 'Encrypted attachment',\n content_type: 'application/octet-stream',\n content_length: projectionOriginal?.cipher_size || 0,\n content_disposition: 'attachment',\n message_id: projection.message_id,\n created_at: projection.created_at,\n updated_at: projection.updated_at,\n e2ee_manifest_missing: true,\n };\n }\n\n const original = manifest.assets.find((asset) => asset.kind === 'original') || manifest.assets[0];\n const display = original?.display || {};\n const nameValue = display.name;\n const mimeValue = display.mime_type;\n const sizeValue = display.size;\n const attachmentTypeValue = display.attachment_type;\n const fileName = typeof nameValue === 'string' && nameValue.trim() ? nameValue : 'Encrypted attachment';\n const mimeType = typeof mimeValue === 'string' && mimeValue.trim() ? mimeValue : 'application/octet-stream';\n const size =\n typeof sizeValue === 'number' && Number.isFinite(sizeValue)\n ? sizeValue\n : original?.plaintext_size || projectionOriginal?.cipher_size || original?.cipher_size || 0;\n const attachmentType =\n attachmentTypeValue === 'voiceRecording'\n ? 'voiceRecording'\n : mimeType.startsWith('image/')\n ? 'image'\n : mimeType.startsWith('video/')\n ? 'video'\n : 'file';\n\n return {\n id: projection.attachment_id,\n attachment_type: attachmentType,\n user_id: projection.created_by_user_id,\n cid: projection.cid,\n url: '',\n thumb_url: '',\n file_name: fileName,\n content_type: mimeType,\n content_length: size,\n content_disposition: 'attachment',\n message_id: projection.message_id,\n created_at: projection.created_at,\n updated_at: projection.updated_at,\n e2ee_manifest: manifest,\n };\n }\n\n private async _withE2eeSendLock<T>(e2eeGroupId: string, task: () => Promise<T>): Promise<T> {\n const previous = this._e2eeSendLockChains.get(e2eeGroupId) || Promise.resolve();\n let release!: () => void;\n const next = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chained = previous.catch(() => undefined).then(() => next);\n this._e2eeSendLockChains.set(e2eeGroupId, chained);\n\n await previous.catch(() => undefined);\n try {\n return await task();\n } finally {\n release();\n if (this._e2eeSendLockChains.get(e2eeGroupId) === chained) {\n this._e2eeSendLockChains.delete(e2eeGroupId);\n }\n }\n }\n\n private _displayOverridesArrayToMap(overrides?: Array<Record<string, unknown> | undefined>) {\n if (!overrides?.length) return undefined;\n const map = new Map<number, Record<string, unknown>>();\n overrides.forEach((value, index) => {\n if (value) map.set(index, value);\n });\n return map;\n }\n\n async enqueueE2eeAttachmentMessage(params: QueuedE2eeAttachmentSendParams): Promise<PendingE2eeSendRecord> {\n if (!params.files.length) throw new Error('[Encryption] enqueueE2eeAttachmentMessage requires at least one file');\n const e2eeGroupId = this._resolveChannelE2eeGroupId(params.cid, this._getActiveChannel(params.cid));\n const displayOverrides = params.displayOverrides\n ? params.files.map((_, index) => params.displayOverrides?.get(index))\n : undefined;\n const now = Date.now();\n const record: PendingE2eeSendRecord = {\n message_id: params.messageId,\n cid: params.cid,\n e2ee_group_id: e2eeGroupId,\n channel_type: params.channelType,\n channel_id: params.channelId,\n text: params.text,\n files: params.files as File[],\n display_overrides: displayOverrides,\n local_attachments: params.localAttachments,\n aad_metadata: params.options,\n retry_count: 0,\n status: 'uploading',\n created_at: now,\n updated_at: now,\n };\n\n await this.storage.savePendingE2eeSend(record);\n void this._processQueuedE2eeAttachmentMessage(record, params);\n return record;\n }\n\n async cancelPendingE2eeSend(messageId: string): Promise<void> {\n this._canceledPendingE2eeSends.add(messageId);\n this._pendingE2eeSendAbortControllers.get(messageId)?.abort();\n const existing = await this.storage.loadPendingE2eeSend(messageId).catch(() => null);\n if (existing) {\n await this.storage.savePendingE2eeSend({\n ...existing,\n status: 'canceled',\n updated_at: Date.now(),\n });\n await this.storage.deletePendingE2eeSend(messageId);\n }\n }\n\n async resumePendingE2eeSends(): Promise<void> {\n if (!this.storage?.listPendingE2eeSends) return;\n let records: PendingE2eeSendRecord[] = [];\n try {\n records = await this.storage.listPendingE2eeSends([\n 'generating_preview',\n 'uploading',\n 'uploaded',\n 'encrypting',\n 'sending',\n 'failed_retryable',\n ]);\n } catch (err) {\n sdkLog('warn', '[Encryption] Failed to list pending E2EE sends for resume', err);\n return;\n }\n\n records\n .filter(\n (record) =>\n ((record.files?.length && record.channel_type && record.channel_id) || record.mls_ciphertext) &&\n record.text !== undefined,\n )\n .forEach((record) => {\n void this._processQueuedE2eeAttachmentMessage(record);\n });\n }\n\n private async _sendPersistedPendingE2eeRecord(record: PendingE2eeSendRecord): Promise<any> {\n if (!record.channel_type || !record.channel_id || !record.mls_ciphertext || record.mls_epoch === undefined) {\n throw new Error('Pending E2EE send is missing persisted send material');\n }\n const envelopeOptions = {\n ...(record.send_envelope || {}),\n ...(record.e2ee_attachment_ids?.length ? { e2ee_attachment_ids: record.e2ee_attachment_ids } : {}),\n ...(record.forward_cid ? { forward_cid: record.forward_cid } : {}),\n ...(record.forward_message_id ? { forward_message_id: record.forward_message_id } : {}),\n ...(record.forward_parent_cid ? { forward_parent_cid: record.forward_parent_cid } : {}),\n };\n\n return await this.e2eeClient!.sendMessage(record.channel_type, record.channel_id, {\n message: {\n id: record.message_id,\n mls_ciphertext: record.mls_ciphertext,\n mls_epoch: record.mls_epoch,\n e2ee_group_id: record.e2ee_group_id,\n ...envelopeOptions,\n },\n });\n }\n\n private async _processQueuedE2eeAttachmentMessage(\n initialRecord: PendingE2eeSendRecord,\n liveParams?: QueuedE2eeAttachmentSendParams,\n ): Promise<void> {\n if (this._pendingE2eeSendJobs.has(initialRecord.message_id)) return;\n this._pendingE2eeSendJobs.add(initialRecord.message_id);\n let record = initialRecord;\n let lastProgressPersistedAt = 0;\n let lastProgressEmittedAt = 0;\n let lastProgressPercent = typeof record.local_progress === 'number' ? record.local_progress : -1;\n const abortController = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n if (abortController) this._pendingE2eeSendAbortControllers.set(initialRecord.message_id, abortController);\n\n const isCanceled = () => this._canceledPendingE2eeSends.has(initialRecord.message_id);\n const throwIfCanceled = () => {\n if (isCanceled() || abortController?.signal.aborted) {\n const error = new Error('Pending E2EE send canceled');\n error.name = 'AbortError';\n throw error;\n }\n };\n\n const savePatch = async (patch: Partial<PendingE2eeSendRecord>) => {\n if (isCanceled()) return;\n record = { ...record, ...patch, updated_at: Date.now() };\n await this.storage.savePendingE2eeSend(record);\n };\n\n try {\n throwIfCanceled();\n const files = record.files || liveParams?.files;\n const channelType = record.channel_type || liveParams?.channelType;\n const channelId = record.channel_id || liveParams?.channelId;\n if (record.status === 'sending' && record.mls_ciphertext) {\n const response = await this._withE2eeSendLock(record.e2ee_group_id, () =>\n this._sendPersistedPendingE2eeRecord(record),\n );\n await this.storage.deletePendingE2eeSend(record.message_id);\n liveParams?.onSuccess?.(response);\n return;\n }\n if (!files?.length || !channelType || !channelId) {\n await savePatch({\n status: 'failed_terminal',\n last_error: 'Missing durable files or channel routing for pending E2EE send',\n });\n return;\n }\n\n const prepared = await this.uploadE2eeAttachments(channelType, channelId, files, {\n displayOverrides: liveParams?.displayOverrides || this._displayOverridesArrayToMap(record.display_overrides),\n signal: abortController?.signal,\n onProgress: (progress) => {\n if (isCanceled()) return;\n const nextStatus: PendingE2eeSendStatus =\n progress.phase === 'generating_preview'\n ? 'generating_preview'\n : progress.phase === 'encrypting'\n ? 'encrypting'\n : 'uploading';\n const nextProgress = Math.max(0, Math.min(100, Math.round(progress.percentage)));\n const now = Date.now();\n const shouldEmit =\n now - lastProgressEmittedAt >= 250 || nextProgress !== lastProgressPercent || nextProgress === 100;\n const shouldPersist =\n now - lastProgressPersistedAt >= 500 || nextProgress !== lastProgressPercent || nextProgress === 100;\n if (shouldPersist) {\n lastProgressPersistedAt = now;\n lastProgressPercent = nextProgress;\n void savePatch({ status: nextStatus, local_progress: nextProgress });\n }\n if (shouldEmit) {\n lastProgressEmittedAt = now;\n liveParams?.onProgress?.({ ...progress, percentage: nextProgress });\n }\n },\n });\n throwIfCanceled();\n\n await savePatch({\n status: 'uploaded',\n manifest: prepared.attachments,\n e2ee_attachment_ids: prepared.e2ee_attachment_ids,\n local_progress: 100,\n });\n\n const sendOptions = {\n ...(record.aad_metadata || {}),\n ...(liveParams?.options || {}),\n attachments: prepared.attachments,\n e2ee_attachment_ids: prepared.e2ee_attachment_ids,\n } as QueuedE2eeAttachmentSendParams['options'] & {\n attachments: E2eeAttachmentManifest[];\n e2ee_attachment_ids: string[];\n };\n\n liveParams?.onProgress?.({\n fileIndex: Math.max(0, files.length - 1),\n phase: 'sending',\n loaded: 1,\n total: 1,\n percentage: 100,\n });\n\n await savePatch({ status: 'sending' });\n throwIfCanceled();\n const response = await this.sendMessage(\n channelType,\n channelId,\n record.cid,\n record.text || '',\n record.message_id,\n sendOptions,\n );\n await this.storage.deletePendingE2eeSend(record.message_id);\n liveParams?.onSuccess?.(response);\n } catch (err) {\n if (isCanceled() || abortController?.signal.aborted) {\n await this.storage.deletePendingE2eeSend(record.message_id).catch(() => undefined);\n return;\n }\n const isTerminal = isE2eeAttachmentInvalidError(err);\n await savePatch({\n status: isTerminal ? 'failed_terminal' : 'failed_retryable',\n retry_count: (record.retry_count || 0) + 1,\n last_error: getApiErrorMessage(err),\n });\n liveParams?.onError?.(err);\n } finally {\n this._pendingE2eeSendJobs.delete(initialRecord.message_id);\n this._pendingE2eeSendAbortControllers.delete(initialRecord.message_id);\n this._canceledPendingE2eeSends.delete(initialRecord.message_id);\n }\n }\n\n /**\n * Send an encrypted E2EE message.\n *\n * Encrypts the full MessageContent::Standard (text + attachments + sticker_url +\n * polls) inside the encryption ciphertext. Server only sees envelope metadata.\n *\n * Returns a full Message object for the sender's local channel state.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async sendMessage(\n channelType: string,\n channelId: string,\n cid: string,\n text: string,\n messageId: string,\n options: {\n parent_id?: string;\n quoted_message_id?: string;\n mentioned_users?: string[];\n mentioned_all?: boolean;\n forward_cid?: string;\n forward_message_id?: string;\n forward_parent_cid?: string;\n e2ee_attachment_ids?: string[];\n /** Attachment metadata — encrypted inside E2EE payload */\n attachments?: unknown[];\n /** Sticker URL — encrypted inside E2EE payload */\n sticker_url?: string;\n /** Poll type — encrypted inside E2EE payload */\n poll_type?: string;\n /** Poll choices — encrypted inside E2EE payload */\n poll_choice_counts?: Record<string, number>;\n } = {},\n ): Promise<any> {\n const e2eeGroupId = this._resolveChannelE2eeGroupId(cid, this._getActiveChannel(cid));\n return await this._withE2eeSendLock(e2eeGroupId, () =>\n this._sendMessageUnlocked(channelType, channelId, cid, text, messageId, options, e2eeGroupId),\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private async _sendMessageUnlocked(\n channelType: string,\n channelId: string,\n cid: string,\n text: string,\n messageId: string,\n options: {\n parent_id?: string;\n quoted_message_id?: string;\n mentioned_users?: string[];\n mentioned_all?: boolean;\n forward_cid?: string;\n forward_message_id?: string;\n forward_parent_cid?: string;\n e2ee_attachment_ids?: string[];\n /** Attachment metadata — encrypted inside E2EE payload */\n attachments?: unknown[];\n /** Sticker URL — encrypted inside E2EE payload */\n sticker_url?: string;\n /** Poll type — encrypted inside E2EE payload */\n poll_type?: string;\n /** Poll choices — encrypted inside E2EE payload */\n poll_choice_counts?: Record<string, number>;\n },\n e2eeGroupId: string,\n ): Promise<any> {\n // Build structured payload — everything inside is encrypted\n const payload: E2eePayload = { text };\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments;\n }\n if (options.sticker_url) {\n payload.sticker_url = options.sticker_url;\n }\n if (options.poll_type) {\n payload.poll_type = options.poll_type;\n }\n if (options.poll_choice_counts) {\n payload.poll_choice_counts = options.poll_choice_counts;\n }\n\n // Strip encrypted fields — only envelope metadata goes to server\n const { attachments: _a, sticker_url: _s, poll_type: _pt, poll_choice_counts: _pc, ...envelopeOptions } = options;\n\n if (!this.getGroup(e2eeGroupId)) {\n const groupParts = channelPartsFromCid(e2eeGroupId);\n const ready = groupParts\n ? await this.ensureChannelReady(groupParts.channelType, groupParts.channelId, e2eeGroupId, { source: 'send' })\n : await this.ensureChannelReady(channelType, channelId, e2eeGroupId, { source: 'send' });\n if (!this.getGroup(e2eeGroupId)) {\n throw new Error(`[Encryption] No group for cid: ${e2eeGroupId}; ensureChannelReady status=${ready.status}`);\n }\n }\n\n // Encrypt and send with epoch-stale retry:\n // After enableE2ee or when offline, other members may commit (external_join,\n // key rotation) advancing the server epoch. Sync group state and retry once.\n const manifestAttachmentIds = this._manifestAttachmentIds(payload);\n const e2eeAttachmentIds = options.e2ee_attachment_ids || manifestAttachmentIds;\n if (e2eeAttachmentIds.length > 0) {\n this._validateEnvelopeAttachmentIds({ e2ee_attachment_ids: e2eeAttachmentIds }, payload);\n }\n const aadParams = {\n cid,\n e2ee_group_id: e2eeGroupId,\n message_id: messageId,\n forward_cid: options.forward_cid,\n forward_message_id: options.forward_message_id,\n forward_parent_cid: options.forward_parent_cid,\n e2ee_attachment_ids: e2eeAttachmentIds,\n };\n const aad = hasE2eeAadMetadata(aadParams) ? buildE2eeMessageAadV1(aadParams) : undefined;\n\n let ciphertext = this.encryptMessage(e2eeGroupId, payload, aad);\n let group = this.getGroup(e2eeGroupId)!;\n let response: any;\n const nowForPending = Date.now();\n const pendingRecordBase: PendingE2eeSendRecord = {\n message_id: messageId,\n cid,\n e2ee_group_id: e2eeGroupId,\n channel_type: channelType,\n channel_id: channelId,\n text,\n mls_ciphertext: ciphertext,\n mls_ciphertext_sha256: ciphertextSha256(ciphertext, this._attachmentCryptoProvider),\n mls_epoch: Number(group.epoch()),\n e2ee_attachment_ids: e2eeAttachmentIds,\n aad_metadata: aad ? aadParams : undefined,\n send_envelope: envelopeOptions as Record<string, unknown>,\n forward_cid: options.forward_cid,\n forward_message_id: options.forward_message_id,\n forward_parent_cid: options.forward_parent_cid,\n manifest: payload.attachments as E2eeAttachmentManifest[] | undefined,\n retry_count: 0,\n status: 'sending',\n created_at: nowForPending,\n updated_at: nowForPending,\n };\n await this._persistProvider();\n await this.storage.savePendingE2eeSend(pendingRecordBase);\n try {\n response = await this.e2eeClient!.sendMessage(channelType, channelId, {\n message: {\n id: messageId,\n mls_ciphertext: ciphertext,\n mls_epoch: Number(group.epoch()),\n e2ee_group_id: e2eeGroupId,\n ...(e2eeAttachmentIds.length > 0 ? { e2ee_attachment_ids: e2eeAttachmentIds } : {}),\n ...envelopeOptions,\n },\n });\n } catch (err) {\n if (isEpochStaleError(err)) {\n sdkLog('warn', '[Encryption] sendMessage: epoch_stale — syncing group and retrying...');\n await this.sync();\n // Re-encrypt with updated epoch after sync\n ciphertext = this.encryptMessage(e2eeGroupId, payload, aad);\n group = this.getGroup(e2eeGroupId)!;\n await this._persistProvider();\n await this.storage.savePendingE2eeSend({\n ...pendingRecordBase,\n mls_ciphertext: ciphertext,\n mls_ciphertext_sha256: ciphertextSha256(ciphertext, this._attachmentCryptoProvider),\n mls_epoch: Number(group.epoch()),\n retry_count: pendingRecordBase.retry_count + 1,\n updated_at: Date.now(),\n });\n try {\n response = await this.e2eeClient!.sendMessage(channelType, channelId, {\n message: {\n id: messageId,\n mls_ciphertext: ciphertext,\n mls_epoch: Number(group.epoch()),\n e2ee_group_id: e2eeGroupId,\n ...(e2eeAttachmentIds.length > 0 ? { e2ee_attachment_ids: e2eeAttachmentIds } : {}),\n ...envelopeOptions,\n },\n });\n } catch (retryErr) {\n await this.storage.savePendingE2eeSend({\n ...pendingRecordBase,\n mls_ciphertext: ciphertext,\n mls_ciphertext_sha256: ciphertextSha256(ciphertext, this._attachmentCryptoProvider),\n mls_epoch: Number(group.epoch()),\n retry_count: pendingRecordBase.retry_count + 1,\n status: 'failed_retryable',\n last_error: getApiErrorMessage(retryErr),\n updated_at: Date.now(),\n });\n throw retryErr;\n }\n } else {\n await this.storage.savePendingE2eeSend({\n ...pendingRecordBase,\n status: 'failed_retryable',\n last_error: getApiErrorMessage(err),\n updated_at: Date.now(),\n });\n throw err;\n }\n }\n await this.storage.savePendingE2eeSend({\n ...pendingRecordBase,\n status: 'sent',\n updated_at: Date.now(),\n });\n\n // Save to local DB with full decrypted Standard content\n const now = new Date().toISOString();\n const storedMsg: E2eeStoredMessage = {\n id: messageId,\n cid,\n content_type: 'standard',\n text,\n attachments: payload.attachments,\n sticker_url: payload.sticker_url,\n poll_type: payload.poll_type,\n poll_choice_counts: payload.poll_choice_counts,\n user_id: this.userId!,\n user: pickUserWithDisplayName(\n this.userId || undefined,\n this.client?.user,\n this.userId ? this.client?.state?.users?.[this.userId] : undefined,\n ),\n created_at: now,\n type: this._messageTypeForPayload(payload),\n parent_id: options.parent_id,\n quoted_message_id: options.quoted_message_id,\n mentioned_users: options.mentioned_users,\n mentioned_all: options.mentioned_all,\n forward_cid: options.forward_cid,\n forward_message_id: options.forward_message_id,\n forward_parent_cid: options.forward_parent_cid,\n e2ee_attachment_ids: e2eeAttachmentIds,\n };\n await this.storage.saveE2eeMessage(storedMsg);\n\n // CRITICAL: Persist Provider to IndexedDB after successful send.\n // create_message() advanced the encryption ratchet generation in-memory\n // and save_state() wrote it to Provider. Without this flush, a tab reload\n // before the next _persistProvider() call would revert the generation\n // counter → next send re-uses consumed generations → forward secrecy error\n // on the receiver side.\n await this._persistProvider();\n\n // Return full message for channel state + server response\n return {\n ...response,\n message: await this._buildFullMessageWithQuoted(storedMsg, {\n forward_cid: options.forward_cid,\n forward_message_id: options.forward_message_id,\n forward_parent_cid: options.forward_parent_cid,\n e2ee_attachment_ids: e2eeAttachmentIds,\n }),\n };\n }\n\n /**\n * Update an encrypted E2EE message by overwriting the server snapshot.\n * The encrypted payload carries the latest text plus cumulative old_texts.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async updateMessage(\n channelType: string,\n channelId: string,\n cid: string,\n messageId: string,\n text: string,\n options: {\n mentioned_users?: string[];\n mentioned_all?: boolean;\n attachments?: unknown[];\n sticker_url?: string;\n poll_type?: string;\n poll_choice_counts?: Record<string, number>;\n } = {},\n ): Promise<any> {\n sdkLog('info', '[Encryption] updateMessage: encrypting edit', {\n cid,\n message_id: messageId,\n });\n const existingForPayload = await this.storage.loadE2eeMessage(messageId);\n const oldTexts = existingForPayload\n ? [\n ...(existingForPayload.old_texts || []),\n {\n text: existingForPayload.text,\n created_at: existingForPayload.updated_at || existingForPayload.created_at || new Date().toISOString(),\n },\n ]\n : [];\n const payload: E2eePayload = { text };\n if (oldTexts.length > 0) {\n payload.old_texts = oldTexts;\n }\n if (options.attachments && options.attachments.length > 0) {\n payload.attachments = options.attachments;\n }\n if (options.sticker_url) {\n payload.sticker_url = options.sticker_url;\n }\n if (options.poll_type) {\n payload.poll_type = options.poll_type;\n }\n if (options.poll_choice_counts) {\n payload.poll_choice_counts = options.poll_choice_counts;\n }\n\n const { attachments: _a, sticker_url: _s, poll_type: _pt, poll_choice_counts: _pc, ...envelopeOptions } = options;\n\n const e2eeGroupId = this._resolveChannelE2eeGroupId(cid, this._getActiveChannel(cid));\n if (!this.getGroup(e2eeGroupId)) {\n const groupParts = channelPartsFromCid(e2eeGroupId);\n const ready = groupParts\n ? await this.ensureChannelReady(groupParts.channelType, groupParts.channelId, e2eeGroupId, { source: 'edit' })\n : await this.ensureChannelReady(channelType, channelId, e2eeGroupId, { source: 'edit' });\n if (!this.getGroup(e2eeGroupId)) {\n throw new Error(`[Encryption] No group for cid: ${e2eeGroupId}; ensureChannelReady status=${ready.status}`);\n }\n }\n\n let ciphertext = this.encryptMessage(e2eeGroupId, payload);\n let group = this.getGroup(e2eeGroupId)!;\n let response: any;\n try {\n response = await this.e2eeClient!.updateMessage(channelType, channelId, messageId, {\n message: {\n mls_ciphertext: ciphertext,\n mls_epoch: Number(group.epoch()),\n e2ee_group_id: e2eeGroupId,\n ...envelopeOptions,\n },\n });\n sdkLog('info', '[Encryption] updateMessage: sent', { cid, message_id: messageId });\n } catch (err) {\n if (isEpochStaleError(err)) {\n sdkLog('warn', '[Encryption] updateMessage: epoch_stale — syncing group and retrying...');\n await this.sync();\n ciphertext = this.encryptMessage(e2eeGroupId, payload);\n group = this.getGroup(e2eeGroupId)!;\n response = await this.e2eeClient!.updateMessage(channelType, channelId, messageId, {\n message: {\n mls_ciphertext: ciphertext,\n mls_epoch: Number(group.epoch()),\n e2ee_group_id: e2eeGroupId,\n ...envelopeOptions,\n },\n });\n } else {\n throw err;\n }\n }\n\n // Update local plaintext cache for own-device edits (encryption cannot decrypt self-sent).\n try {\n const existing = existingForPayload || (await this.storage.loadE2eeMessage(messageId));\n if (existing) {\n await this.storage.saveE2eeMessage({\n ...existing,\n content_type: 'standard',\n text,\n is_edited: true,\n updated_at: new Date().toISOString(),\n old_texts: oldTexts,\n attachments: payload.attachments || existing.attachments,\n sticker_url: payload.sticker_url || existing.sticker_url,\n poll_type: payload.poll_type || existing.poll_type,\n poll_choice_counts: payload.poll_choice_counts || existing.poll_choice_counts,\n type: this._messageTypeForPayload(payload, existing.type),\n mentioned_users: options.mentioned_users || existing.mentioned_users,\n mentioned_all: options.mentioned_all !== undefined ? options.mentioned_all : existing.mentioned_all,\n });\n } else {\n await this.storage.saveE2eeMessage({\n id: messageId,\n cid,\n content_type: 'standard',\n text,\n attachments: payload.attachments,\n sticker_url: payload.sticker_url,\n poll_type: payload.poll_type,\n poll_choice_counts: payload.poll_choice_counts,\n user_id: this.userId!,\n user: pickUserWithDisplayName(\n this.userId || undefined,\n this.client?.user,\n this.userId ? this.client?.state?.users?.[this.userId] : undefined,\n ),\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n type: this._messageTypeForPayload(payload),\n mentioned_users: options.mentioned_users,\n mentioned_all: options.mentioned_all,\n is_edited: true,\n old_texts: [],\n });\n }\n } catch (err) {\n sdkLog('warn', '[Encryption] updateMessage: failed to update local cache:', messageId, err);\n }\n\n // Persist Provider snapshot after encrypting an edit.\n await this._persistProvider();\n\n return response;\n }\n\n // ============================================================\n // Waterfall Decryption\n // ============================================================\n\n /**\n * Decrypt application messages in epoch order (waterfall).\n *\n * Protocol events (commits/welcomes) must be processed BEFORE calling this.\n * Messages are sorted by created_at and decrypted sequentially.\n */\n async decryptApplicationMessages(\n cid: string,\n encryptedMessages: Array<{\n id: string;\n mls_ciphertext?: Uint8Array;\n e2ee_group_id?: string;\n user?: { id: string };\n created_at: string;\n mls_epoch?: number;\n [key: string]: unknown;\n }>,\n e2eeGroupId?: string,\n ): Promise<WaterfallResult> {\n const decrypted: E2eeStoredMessage[] = [];\n const buffered: unknown[] = [];\n let expectedRecoveryFailures = 0;\n let decryptFailures = 0;\n let missingGroupCount = 0;\n let consumedCount = 0;\n\n // Sort by created_at ascending for correct epoch processing\n const sorted = [...encryptedMessages].sort(\n (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime(),\n );\n\n for (const msg of sorted) {\n if (!msg.mls_ciphertext) continue;\n const routeCid = (typeof msg.cid === 'string' && msg.cid) || cid;\n const groupCid = this._resolveMessageE2eeGroupId(msg, e2eeGroupId || cid);\n if (this._isEncryptionProcessingBlockedForRoute(routeCid, groupCid)) {\n buffered.push(msg);\n this._logDeferredEncryptionEventOnce('pending_invite_waterfall', routeCid, groupCid, msg.id);\n continue;\n }\n\n const group = this.groups.get(groupCid);\n if (!group) {\n buffered.push(msg);\n missingGroupCount += 1;\n this._logDeferredEncryptionEventOnce('missing_local_group_waterfall', routeCid, groupCid, msg.id);\n await this._recordRepairIssue(routeCid, msg, 'missing_local_snapshot', false);\n continue;\n }\n\n // Skip messages already decrypted & stored for this version (encryption forward secrecy:\n // keys are consumed after first use, re-decrypting would fail)\n const existing = await this.storage.loadE2eeMessage(msg.id);\n if (existing && this._storedMessageCoversVersion(existing, msg)) {\n decrypted.push(existing);\n await this._clearRepairIssue(routeCid, msg);\n continue;\n }\n\n try {\n const { payload, messageType } = this.decryptMessage(groupCid, msg.mls_ciphertext);\n\n // Mark as decrypted IMMEDIATELY after process_message succeeds —\n // before async IndexedDB write. This prevents the race where WS\n // message.new arrives before saveE2eeMessage() flushes to IndexedDB.\n this._decryptedMsgIds.add(this._messageVersionKey(msg));\n\n if (messageType === 0) {\n const fallback = await this.storage.loadE2eeMessage(msg.id);\n const decryptedMsg = this._storedFromPayload(routeCid, payload, msg, fallback);\n await this.storage.saveE2eeMessage(decryptedMsg);\n await this._clearRepairIssue(routeCid, msg);\n decrypted.push(decryptedMsg);\n }\n } catch (err) {\n const errMsg = (err as Error).message || '';\n if (this._isForwardSecrecyConsumedError(errMsg)) {\n this._decryptedMsgIds.add(this._messageVersionKey(msg));\n await this._recordRepairIssue(routeCid, msg, 'forward_secrecy_consumed', false);\n consumedCount += 1;\n this._logExpectedDecryptFailureOnce(routeCid, msg, this._safeGroupEpoch(group), errMsg);\n continue;\n }\n buffered.push(msg);\n if (this._isExpectedRecoverableDecryptFailure(group, msg, errMsg)) {\n expectedRecoveryFailures += 1;\n await this._recordRepairIssue(routeCid, msg, 'decrypt_error', false);\n this._logExpectedDecryptFailureOnce(routeCid, msg, this._safeGroupEpoch(group), errMsg);\n } else {\n decryptFailures += 1;\n await this._recordRepairIssue(routeCid, msg, 'decrypt_error');\n }\n }\n }\n\n if (decrypted.length > 0) {\n await this._persistProvider();\n }\n\n const groupLabel = e2eeGroupId || cid;\n const summaryKey = [\n cid,\n groupLabel,\n decrypted.length,\n buffered.length,\n expectedRecoveryFailures,\n decryptFailures,\n missingGroupCount,\n consumedCount,\n ].join(':');\n if (\n (decrypted.length > 0 || buffered.length > 0) &&\n this._shouldLogThrottled(this._waterfallSummaryLogKeys, summaryKey, ENCRYPTION_WATERFALL_SUMMARY_LOG_TTL_MS)\n ) {\n const summary = {\n cid,\n group: groupLabel,\n decrypted: decrypted.length,\n buffered: buffered.length,\n pendingRecovery: expectedRecoveryFailures,\n missingLocalGroup: missingGroupCount,\n consumed: consumedCount,\n decryptFailures,\n };\n if (decryptFailures > 0) {\n sdkLog('warn', '[Encryption] Waterfall decrypt completed with unexpected failures:', summary);\n } else {\n sdkLog('info', '[Encryption] Waterfall decrypt summary:', summary);\n }\n }\n return { decrypted, buffered };\n }\n\n // ============================================================\n // Cleanup\n // ============================================================\n\n /**\n * Destroy the encryption manager — free WASM objects and clean up all in-memory state.\n *\n * Call this during `disconnectUser()` to prevent stale state\n * from leaking into the next user session.\n *\n * Does NOT delete IndexedDB data (user-scoped DB preserves\n * state for when the same user logs back in).\n */\n destroy(): void {\n const groups = Array.from(this.groups.values());\n for (let i = 0; i < groups.length; i++) {\n try {\n groups[i].free();\n } catch (e) {\n // ignore\n }\n }\n this.groups.clear();\n\n if (this.identity) {\n try {\n this.identity.free();\n } catch (e) {\n // ignore\n }\n }\n\n if (this.provider) {\n try {\n this.provider.free();\n } catch (e) {\n // ignore\n }\n }\n\n this.initialized = false;\n this.provider = null;\n this.identity = null;\n this.userId = null;\n this.deviceId = null;\n this.e2eeClient = null;\n this.client = null;\n this._recoveryPrivateKey = null;\n this._recoveryPublicKey = null;\n this._recoveryKeyId = null;\n this._recoveryCiphersuite = null;\n this._wrappedRecoveryKey = null;\n this._recoveryVaultKnown = null;\n this._recoveryVaultBytes = null;\n this._recoveryVaultRevision = null;\n this._recoveryPublicMetadataPromise = null;\n this._archiveStashKey = null;\n this._archiveStashKeyPromise = null;\n this._recoveryPostUnlockMaintenancePromise = null;\n this._recoveryPostUnlockMaintenanceGeneration += 1;\n this._expectedDecryptLogKeys.clear();\n this._waterfallSummaryLogKeys.clear();\n this._deferredEncryptionEventLogKeys.clear();\n this._restoreQueue = [];\n this._restoreQueueRunning = false;\n this._restoreInflight.clear();\n this._bootstrapKnownChannelsPromise = null;\n this._channelBootstrapSub?.unsubscribe?.();\n this._channelBootstrapSub = null;\n this._e2eeBootstrapProgress = {\n total: 0,\n completed: 0,\n failed_cids: [],\n status: 'idle',\n };\n this._decryptedMsgIds.clear();\n this._pendingEvictions.clear();\n this._syncing = false;\n this._syncPromise = null;\n this._syncWorkPromise = null;\n this._syncGateResolve = null;\n this._lastSyncStates.clear();\n this._channelReadyLocks.clear();\n this._channelReadyUntil.clear();\n this._providerRestored = false;\n // Reset storage so next initialize() creates a new user-scoped instance\n this.storage = null as unknown as EncryptionStorageAdapter;\n sdkLog('info', '[Encryption] Manager destroyed');\n }\n // ============================================================\n // E2EE Topic Operations\n // ============================================================\n\n /**\n * Prepare encryption bundle for creating a new E2EE topic.\n *\n * Mirrors `createE2eeChannel` but for a topic within a parent channel.\n * Creates a new encryption group, adds all parent members, and returns the bundle\n * that the caller passes to `channel.createTopic({ mls_enabled: true, ...bundle })`.\n *\n * @param topicCid - e.g. \"topic:proj-uuid\"\n * @param parentMemberUserIds - all member user IDs from the parent channel\n */\n async createE2eeTopic(\n topicCid: string,\n parentMemberUserIds: string[],\n ): Promise<{\n commit: Uint8Array;\n welcome: Uint8Array;\n ratchet_tree: Uint8Array;\n group_info: Uint8Array;\n epoch: number;\n }> {\n if (!this.initialized) throw new Error('[Encryption] Not initialized');\n\n // 1. Create encryption group (solo — just creator, epoch 0)\n const group = this.createGroup(topicCid);\n\n // 2. Fetch key packages for all members via batch API (no channel needed)\n // Server auto-excludes sender; members without KPs are silently omitted.\n const { members } = await this.e2eeClient!.getKeyPackagesByUserIds(parentMemberUserIds);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const allKeyPackages: any[] = [];\n for (const member of members) {\n for (const kpData of member.key_packages) {\n const kp = wasmModule.KeyPackage.from_bytes(new Uint8Array(kpData.key_package));\n allKeyPackages.push(kp);\n }\n }\n\n // 3. Add members → commit + welcome (or solo commit if no KPs)\n const commitBundle =\n allKeyPackages.length > 0\n ? group.add_members(this.provider, this.identity, allKeyPackages)\n : group.commit_pending_proposals(this.provider, this.identity);\n\n // 4. Export ratchet tree\n const ratchetTree = group.export_ratchet_tree();\n\n // 5. Get group_info from commitBundle\n const exportedGI = commitBundle.group_info;\n if (!exportedGI || exportedGI.length === 0) {\n group.clear_pending_commit(this.provider);\n await this._persistProvider();\n throw new Error('[Encryption] createE2eeTopic: commitBundle.group_info is empty — cannot proceed');\n }\n\n // 6. Capture pre-merge epoch\n const premergeEpoch = Number(group.epoch());\n\n // 7. Merge commit locally (group advances to epoch N+1)\n group.merge_pending_commit(this.provider);\n await this._persistProvider();\n\n sdkLog('info', '[Encryption] createE2eeTopic: bundle ready for:', topicCid, 'epoch:', Number(group.epoch()));\n\n return {\n commit: commitBundle.commit,\n welcome: allKeyPackages.length > 0 ? commitBundle.welcome : new Uint8Array(0),\n ratchet_tree: ratchetTree.to_bytes(),\n group_info: exportedGI,\n epoch: premergeEpoch,\n };\n }\n\n /**\n * Batch add members to N E2EE topics.\n *\n * WASM operations are sequential (state integrity), but the API call is batched\n * into a single request. For each topic, creates add_members commit+welcome,\n * then sends all bundles at once.\n *\n * @param parentChannelType - parent channel type (e.g. \"team\")\n * @param parentChannelId - parent channel ID\n * @param topicCids - list of topic CIDs to add members to\n * @param newUserIds - user IDs being added\n */\n async batchAddMembersToTopics(\n parentChannelType: string,\n parentChannelId: string,\n topicCids: string[],\n newUserIds: string[],\n ): Promise<{ results: Array<{ topic_cid: string; success: boolean; error?: string; epoch?: number }> }> {\n if (!this.initialized) throw new Error('[Encryption] Not initialized');\n const ownGroupTopicCids = topicCids.filter((topicCid) => this._topicOwnsE2eeGroup(topicCid));\n if (ownGroupTopicCids.length === 0) return { results: [] };\n\n // 1. Fetch KPs for new users — need N KPs per device (N = number of topics)\n const countPerDevice = ownGroupTopicCids.length;\n const { members } = await this.e2eeClient!.getKeyPackagesByUserIds(newUserIds, countPerDevice);\n\n // 2. Build per-device KP queue: deviceId → [kp1, kp2, ..., kpN]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const deviceKpQueues = new Map<string, any[]>();\n for (const member of members) {\n for (const kpData of member.key_packages) {\n const key = `${member.user_id}:${kpData.device_id}`;\n if (!deviceKpQueues.has(key)) deviceKpQueues.set(key, []);\n const kp = wasmModule.KeyPackage.from_bytes(new Uint8Array(kpData.key_package));\n deviceKpQueues.get(key)!.push(kp);\n }\n }\n\n // 3. Sequential WASM: create bundle for each topic\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const topicBundles: any[] = [];\n const processedCids: string[] = [];\n const topicGhostsByCid = new Map<string, string[]>();\n\n for (let i = 0; i < ownGroupTopicCids.length; i++) {\n const topicCid = ownGroupTopicCids[i];\n const group = this.groups.get(topicCid);\n if (!group) {\n sdkLog('warn', '[Encryption] batchAddMembersToTopics: no group for', topicCid, '— skipping');\n continue;\n }\n\n // Pick KP[i] from each device's queue\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const kpsForThisTopic: any[] = [];\n for (const [, queue] of deviceKpQueues) {\n if (i < queue.length) {\n kpsForThisTopic.push(queue[i]);\n }\n }\n\n if (kpsForThisTopic.length === 0) {\n sdkLog('warn', '[Encryption] batchAddMembersToTopics: no KPs available for topic', topicCid);\n continue;\n }\n\n try {\n this._requireCompositeCommitMethods(group);\n const ghostsToRemove = await this._collectPendingGhosts(topicCid, newUserIds);\n const commitBundle = group.commit_member_add_with_removals(\n this.provider,\n this.identity,\n ghostsToRemove,\n kpsForThisTopic,\n );\n const ratchetTree = group.export_ratchet_tree();\n const groupInfo = commitBundle.group_info;\n\n if (!groupInfo || groupInfo.length === 0) {\n group.clear_pending_commit(this.provider);\n sdkLog('error', '[Encryption] batchAddMembersToTopics: empty group_info for', topicCid);\n continue;\n }\n\n topicBundles.push({\n topic_cid: topicCid,\n commit: commitBundle.commit,\n welcome: commitBundle.welcome,\n ratchet_tree: ratchetTree.to_bytes(),\n group_info: groupInfo,\n epoch: Number(group.epoch()),\n });\n processedCids.push(topicCid);\n topicGhostsByCid.set(topicCid, ghostsToRemove);\n } catch (err) {\n sdkLog('error', '[Encryption] batchAddMembersToTopics: WASM error for', topicCid, err);\n }\n }\n\n if (topicBundles.length === 0) {\n return { results: [] };\n }\n\n // 4. Batch API call\n let response;\n try {\n response = await this.e2eeClient!.batchAddMembersToTopics(parentChannelType, parentChannelId, {\n target_user_ids: newUserIds,\n topics: topicBundles,\n });\n } catch (err) {\n // Server rejected entirely → clear all pending commits\n for (const cid of processedCids) {\n const g = this.groups.get(cid);\n if (g) {\n g.clear_pending_commit(this.provider);\n }\n }\n await this._persistProvider();\n throw err;\n }\n\n // 5. For each successful topic → merge pending commit\n for (const result of response.results) {\n const g = this.groups.get(result.topic_cid);\n if (!g) continue;\n\n if (result.success) {\n g.merge_pending_commit(this.provider);\n await this._cleanupEvictedGhosts(result.topic_cid, topicGhostsByCid.get(result.topic_cid) ?? []);\n sdkLog('info', '[Encryption] batchAddMembers: merged', result.topic_cid, 'epoch:', result.epoch);\n } else {\n g.clear_pending_commit(this.provider);\n sdkLog('warn', '[Encryption] batchAddMembers: failed', result.topic_cid, result.error);\n }\n }\n\n await this._persistProvider();\n for (const result of response.results) {\n if (result.success) {\n await this.safeArchiveCurrentEpochForCid(result.topic_cid);\n }\n }\n return response;\n }\n\n /**\n * Batch external join for N E2EE topics (multi-device).\n *\n * For each topic, fetches GroupInfo → creates external commit → collects all → sends batch request.\n *\n * @param parentChannelType - parent channel type\n * @param parentChannelId - parent channel ID\n * @param topicCids - list of E2EE topic CIDs to join\n */\n async batchExternalJoinTopics(\n parentChannelType: string,\n parentChannelId: string,\n topicCids: string[],\n ): Promise<{ results: Array<{ topic_cid: string; success: boolean; error?: string; epoch?: number }> }> {\n if (!this.initialized) throw new Error('[Encryption] Not initialized');\n const ownGroupTopicCids = topicCids.filter(\n (topicCid) => this._resolveChannelE2eeGroupId(topicCid, this._getActiveChannel(topicCid)) === topicCid,\n );\n if (ownGroupTopicCids.length === 0) return { results: [] };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const topicBundles: any[] = [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const pendingGroups = new Map<string, any>();\n\n // 1. Sequential: fetch GroupInfo + external join for each topic\n for (const topicCid of ownGroupTopicCids) {\n try {\n // Extract channelType/channelId from topic CID\n const colonIdx = topicCid.indexOf(':');\n const topicChannelId = topicCid.substring(colonIdx + 1);\n\n // Fetch GroupInfo\n const { group_info } = await this.e2eeClient!.getGroupInfo('topic', topicChannelId);\n\n // WASM: External join\n const result = wasmModule.Group.join_external(this.provider, this.identity, new Uint8Array(group_info), null);\n const group = result.group;\n if (!group) {\n sdkLog('error', '[Encryption] batchExternalJoin: no group for', topicCid);\n continue;\n }\n\n pendingGroups.set(topicCid, group);\n topicBundles.push({\n topic_cid: topicCid,\n commit: result.commit,\n epoch: Number(group.epoch()),\n // group_info is uploaded separately after merge\n });\n } catch (err) {\n sdkLog('error', '[Encryption] batchExternalJoin: error for', topicCid, err);\n }\n }\n\n if (topicBundles.length === 0) {\n return { results: [] };\n }\n\n // 2. Batch API call\n let response;\n try {\n response = await this.e2eeClient!.batchExternalJoinTopics(parentChannelType, parentChannelId, {\n topics: topicBundles,\n });\n } catch (err) {\n // Server rejected entirely → clear all pending commits\n for (const [, group] of pendingGroups) {\n try {\n group.clear_pending_commit(this.provider);\n } catch (e) {\n /* ignore */\n }\n }\n await this._persistProvider();\n throw err;\n }\n\n // 3. For each successful topic → merge + cache + upload GroupInfo\n for (const result of response.results) {\n const group = pendingGroups.get(result.topic_cid);\n if (!group) continue;\n\n if (result.success) {\n group.merge_pending_commit(this.provider);\n this.groups.set(result.topic_cid, group);\n await this._saveGroup(result.topic_cid);\n\n // Extract channel parts for getGroupInfo upload\n const colonIdx = result.topic_cid.indexOf(':');\n const topicChannelId = result.topic_cid.substring(colonIdx + 1);\n await this._uploadGroupInfo('topic', topicChannelId, group);\n\n // Save cursor\n await this._saveScopeSyncCursor(result.topic_cid, this._nowEventCursor());\n\n sdkLog('info', '[Encryption] batchExternalJoin: joined', result.topic_cid, 'epoch:', result.epoch);\n } else {\n try {\n group.clear_pending_commit(this.provider);\n } catch (e) {\n /* ignore */\n }\n sdkLog('warn', '[Encryption] batchExternalJoin: failed', result.topic_cid, result.error);\n }\n }\n\n await this._persistProvider();\n for (const result of response.results) {\n if (result.success) {\n await this.safeArchiveCurrentEpochForCid(result.topic_cid);\n }\n }\n return response;\n }\n}\n","export type OpenMlsWasmModule = typeof import('./wasm/openmls_wasm');\n\nconst wasmModuleCache = new Map<string, Promise<OpenMlsWasmModule>>();\n\nexport async function loadOpenMlsWasm(wasmPath = '/openmls_wasm_bg.wasm'): Promise<OpenMlsWasmModule> {\n const cacheKey = wasmPath;\n let promise = wasmModuleCache.get(cacheKey);\n\n if (!promise) {\n promise = (async () => {\n const wasmModule = await import('./wasm/openmls_wasm.js');\n await wasmModule.default(wasmPath);\n wasmModule.init();\n return wasmModule;\n })();\n wasmModuleCache.set(cacheKey, promise);\n }\n\n return promise;\n}\n","export type E2eeMediaMp4ProbeResult = {\n ok: boolean;\n reason?: string;\n codecMimeType?: string;\n hasFtyp: boolean;\n hasMoov: boolean;\n hasMoof: boolean;\n hasMdat: boolean;\n};\n\ntype Mp4Box = {\n type: string;\n start: number;\n headerSize: number;\n end: number;\n};\n\nfunction readU32(bytes: Uint8Array, offset: number): number {\n return ((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]) >>> 0;\n}\n\nfunction readU64(bytes: Uint8Array, offset: number): number | undefined {\n const high = readU32(bytes, offset);\n const low = readU32(bytes, offset + 4);\n const value = high * 2 ** 32 + low;\n return Number.isSafeInteger(value) ? value : undefined;\n}\n\nfunction readAscii(bytes: Uint8Array, offset: number, length: number): string {\n let value = '';\n for (let i = 0; i < length; i += 1) value += String.fromCharCode(bytes[offset + i]);\n return value;\n}\n\nfunction parseTopLevelBoxes(bytes: Uint8Array): Mp4Box[] {\n const boxes: Mp4Box[] = [];\n let offset = 0;\n while (offset + 8 <= bytes.length) {\n const size32 = readU32(bytes, offset);\n const type = readAscii(bytes, offset + 4, 4);\n let headerSize = 8;\n let size = size32;\n if (size32 === 1) {\n if (offset + 16 > bytes.length) break;\n const largeSize = readU64(bytes, offset + 8);\n if (largeSize === undefined) break;\n size = largeSize;\n headerSize = 16;\n } else if (size32 === 0) {\n size = bytes.length - offset;\n }\n if (size < headerSize || offset + size > bytes.length) break;\n boxes.push({ type, start: offset, headerSize, end: offset + size });\n offset += size;\n }\n return boxes;\n}\n\nfunction boxPayload(bytes: Uint8Array, box: Mp4Box): Uint8Array {\n return bytes.slice(box.start + box.headerSize, box.end);\n}\n\nfunction containsAscii(bytes: Uint8Array, value: string): boolean {\n const needle = new TextEncoder().encode(value);\n outer: for (let i = 0; i <= bytes.length - needle.length; i += 1) {\n for (let j = 0; j < needle.length; j += 1) {\n if (bytes[i + j] !== needle[j]) continue outer;\n }\n return true;\n }\n return false;\n}\n\nfunction unsupportedContainer(mimeType?: string, fileName?: string): string | undefined {\n const mime = mimeType?.toLowerCase() || '';\n const name = fileName?.toLowerCase() || '';\n if (mime === 'video/quicktime' || name.endsWith('.mov')) return 'mov_unsupported';\n if (mime && mime !== 'video/mp4' && mime !== 'video/x-m4v' && mime !== 'video/m4v') return 'container_unsupported';\n return undefined;\n}\n\nfunction codecMimeFromMoov(moov: Uint8Array): { codecMimeType?: string; reason?: string } {\n if (containsAscii(moov, 'hvc1') || containsAscii(moov, 'hev1')) return { reason: 'hevc_unsupported' };\n const videoCodec = containsAscii(moov, 'avc1')\n ? 'avc1.42E01E'\n : containsAscii(moov, 'avc3')\n ? 'avc3.42E01E'\n : undefined;\n if (!videoCodec) return { reason: 'video_codec_unsupported' };\n const codecs = [videoCodec];\n if (containsAscii(moov, 'mp4a')) codecs.push('mp4a.40.2');\n return { codecMimeType: `video/mp4; codecs=\"${codecs.join(', ')}\"` };\n}\n\nexport function probeE2eeMediaMp4ForMse(input: {\n bytes: Uint8Array;\n mimeType?: string;\n fileName?: string;\n}): E2eeMediaMp4ProbeResult {\n const boxes = parseTopLevelBoxes(input.bytes);\n const ftyp = boxes.find((box) => box.type === 'ftyp');\n const moov = boxes.find((box) => box.type === 'moov');\n const moof = boxes.find((box) => box.type === 'moof');\n const mdat = boxes.find((box) => box.type === 'mdat');\n const base = {\n hasFtyp: Boolean(ftyp),\n hasMoov: Boolean(moov),\n hasMoof: Boolean(moof),\n hasMdat: Boolean(mdat),\n };\n const containerReason = unsupportedContainer(input.mimeType, input.fileName);\n if (containerReason) return { ok: false, reason: containerReason, ...base };\n if (!ftyp) return { ok: false, reason: 'ftyp_missing', ...base };\n if (!moov) return { ok: false, reason: 'moov_missing_in_probe', ...base };\n if (!moof) return { ok: false, reason: 'moof_missing', ...base };\n if (!mdat) return { ok: false, reason: 'mdat_missing', ...base };\n const codec = codecMimeFromMoov(boxPayload(input.bytes, moov));\n if (!codec.codecMimeType) return { ok: false, reason: codec.reason || 'codec_unsupported', ...base };\n return { ok: true, codecMimeType: codec.codecMimeType, ...base };\n}\n","export const E2EE_MEDIA_STREAM_PREFETCH_FRAMES = 8;\nexport const E2EE_MEDIA_STREAM_PREFETCH_THRESHOLD_FRAMES = 2;\nexport const E2EE_MEDIA_STREAM_SEQUENTIAL_PREFETCH_HITS = 2;\nexport const E2EE_MEDIA_STREAM_BASE_SESSION_CACHE_LIMIT = 16 * 1024 * 1024;\nexport const E2EE_MEDIA_STREAM_FULL_REPLAY_CACHE_LIMIT = 128 * 1024 * 1024;\nexport const E2EE_MEDIA_STREAM_GLOBAL_CACHE_LIMIT = 256 * 1024 * 1024;\n\nexport type E2eeMediaFrameBatchPlan = {\n firstFrame: number;\n lastFrame: number;\n prefetch: boolean;\n};\n\nexport type E2eeMediaFrameBatchPlanInput = {\n currentFrame: number;\n lastFrame: number;\n rangeFrameSpan?: number;\n noRange?: boolean;\n sequentialHits?: number;\n prefetchedUntilFrame?: number;\n prefetchFrames?: number;\n prefetchThresholdFrames?: number;\n sequentialPrefetchHits?: number;\n};\n\nfunction nonNegativeInteger(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0) throw new Error(`${label} must be a non-negative integer`);\n return value;\n}\n\nfunction positiveInteger(value: number, label: string): number {\n if (!Number.isInteger(value) || value <= 0) throw new Error(`${label} must be a positive integer`);\n return value;\n}\n\nexport function planE2eeMediaFrameBatch(input: E2eeMediaFrameBatchPlanInput): E2eeMediaFrameBatchPlan {\n const currentFrame = nonNegativeInteger(input.currentFrame, 'currentFrame');\n const lastFrame = nonNegativeInteger(input.lastFrame, 'lastFrame');\n if (currentFrame > lastFrame) throw new Error('currentFrame must be <= lastFrame');\n\n const prefetchFrames = positiveInteger(input.prefetchFrames || E2EE_MEDIA_STREAM_PREFETCH_FRAMES, 'prefetchFrames');\n const prefetchThresholdFrames = positiveInteger(\n input.prefetchThresholdFrames || E2EE_MEDIA_STREAM_PREFETCH_THRESHOLD_FRAMES,\n 'prefetchThresholdFrames',\n );\n const sequentialPrefetchHits = positiveInteger(\n input.sequentialPrefetchHits || E2EE_MEDIA_STREAM_SEQUENTIAL_PREFETCH_HITS,\n 'sequentialPrefetchHits',\n );\n const sequentialHits =\n input.sequentialHits === undefined ? 0 : nonNegativeInteger(input.sequentialHits, 'sequentialHits');\n const prefetchedUntilFrame =\n input.prefetchedUntilFrame === undefined\n ? -1\n : nonNegativeInteger(input.prefetchedUntilFrame, 'prefetchedUntilFrame');\n const rangeFrameSpan =\n input.rangeFrameSpan === undefined\n ? lastFrame - currentFrame + 1\n : positiveInteger(input.rangeFrameSpan, 'rangeFrameSpan');\n const prefetch =\n Boolean(input.noRange) || rangeFrameSpan > prefetchThresholdFrames || sequentialHits >= sequentialPrefetchHits;\n const shouldExtendPrefetch = prefetch && currentFrame > prefetchedUntilFrame;\n\n return {\n firstFrame: currentFrame,\n lastFrame: shouldExtendPrefetch ? Math.min(lastFrame, currentFrame + prefetchFrames - 1) : currentFrame,\n prefetch,\n };\n}\n\nexport function e2eeMediaFramePlainLength(input: {\n frameIndex: number;\n frameSize: number;\n plaintextSize: number;\n}): number {\n const frameIndex = nonNegativeInteger(input.frameIndex, 'frameIndex');\n const frameSize = positiveInteger(input.frameSize, 'frameSize');\n const plaintextSize = nonNegativeInteger(input.plaintextSize, 'plaintextSize');\n const start = frameIndex * frameSize;\n return Math.max(0, Math.min(frameSize, plaintextSize - start));\n}\n\nexport function e2eeMediaSessionCacheLimit(input: {\n plaintextSize: number;\n baseSessionCacheLimit?: number;\n fullReplayCacheLimit?: number;\n}): number {\n const plaintextSize = nonNegativeInteger(input.plaintextSize, 'plaintextSize');\n const baseSessionCacheLimit = positiveInteger(\n input.baseSessionCacheLimit || E2EE_MEDIA_STREAM_BASE_SESSION_CACHE_LIMIT,\n 'baseSessionCacheLimit',\n );\n const fullReplayCacheLimit = positiveInteger(\n input.fullReplayCacheLimit || E2EE_MEDIA_STREAM_FULL_REPLAY_CACHE_LIMIT,\n 'fullReplayCacheLimit',\n );\n if (plaintextSize > 0 && plaintextSize <= fullReplayCacheLimit) {\n return Math.max(baseSessionCacheLimit, plaintextSize);\n }\n return baseSessionCacheLimit;\n}\n"],"mappings":"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","names":["ptr","module","MiniSearch","hex","import_utils","arrayBufferFrom","hex","loaded","offset","total","randomId","ZERO_EVENT_ID","bytesToHex","pending","issue","failCount","requiresPin","messageRepair","result","encoder","existing","init","uploadedOriginal","completeRequest","manifest","response","wasmModule","readU32"]}