---
sdk = "browser-sdk"
previous_release_version = "7.0.0"
---

# Browser SDK 7.1.0

## Highlights

- **`@xmtp/browser-sdk` now ships from the [libxmtp](https://github.com/xmtp/libxmtp) monorepo**, released in lockstep with `@xmtp/wasm-bindings`. The package name and install instructions are unchanged.
- **Idempotency keys on sends**, so a retried send produces the same message ID instead of a duplicate.
- **The `send*` helpers take an options object** instead of a bare `isOptimistic` boolean — the one breaking change in this release.
- **Background worker tuning** via `workerConfig`, and an option to wait for a new installation to become visible on the network before using it.

## What's Changed

Sends now carry an optional idempotency key, and the per-content-type `send*` helpers take a `SendOpts` object so optimistic delivery and the idempotency key can be set together. The same change flows through the worker bridge, so the `conversation.send*` worker actions carry `opts` instead of `isOptimistic`.

Underneath, the two API connections each client used to open have been collapsed into one, background workers are configurable via `workerConfig`, and client creation can wait for a quorum of nodes to confirm a new installation is visible.

This release also picks up the reliability fixes in `@xmtp/wasm-bindings` 1.11.0 — see the [Bug Fixes](#bug-fixes) section.

## Breaking Changes

### The `send*` helpers take a `SendOpts` object instead of `isOptimistic`

**This is a breaking change.**

```ts
// Before
await conversation.sendText("gm", true);

// After
await conversation.sendText("gm", { optimistic: true });
```

This applies to `sendText`, `sendMarkdown`, `sendReaction`, `sendReadReceipt`, `sendReply`, `sendAttachment`, `sendRemoteAttachment`, `sendMultiRemoteAttachment`, `sendTransactionReference`, `sendWalletSendCalls`, `sendActions`, and `sendIntent`.

`SendOpts` is exported from the package:

```ts
import type { SendOpts } from "@xmtp/browser-sdk";
```

If you drive the worker directly, the `conversation.send*` actions now take `opts?: SendOpts` in place of `isOptimistic?: boolean`.

## New Features

### Idempotency keys on sends

Both `SendMessageOpts` (on `conversation.send`) and `SendOpts` (on the `send*` helpers) accept `idempotencyKey`. Re-sending identical content with the same key produces the same message ID and is deduplicated, so a retry after a dropped connection does not create a second message. Defaults to a timestamp when omitted.

```ts
await conversation.sendText("gm", { idempotencyKey: "greeting-2026-07-28" });
```

### Background worker configuration

`ClientOptions.workerConfig` tunes the background worker scheduler — a global default interval, per-worker interval and jitter overrides, and a list of workers to disable. Kinds come from the `WorkerKind` enum, exported from the package: `DeviceSync`, `DisappearingMessages`, `KeyPackageCleaner`, `CommitLog`, `TaskRunner`. Use the enum members (`WorkerKind.DeviceSync`), not string literals.

### Wait for registration to become visible on the network

`ClientOptions.waitForRegistrationVisible` accepts `{ quorumPercentage?, quorumAbsolute?, timeoutMs? }`. When set, client creation waits until a quorum of nodes confirms the new identity and key package are visible before returning, which avoids racing a just-registered installation against propagation.

## Bug Fixes

- **`streamMessageDeletions` never invoked its close handler.** The stream now signals close when it ends, matching the other streams.
- **Logging initialization no longer fails hard** when a `tracing` subscriber is already installed — it warns and continues.
- **Crash on the welcome stream** after a group's creator left the group and was later re-added.
- **False-positive fork detection** after a member was removed from a group.
- **Missed messages in streams** after a recoverable error: the stream resumed past envelopes it had not yet delivered.
- **Cache read returning wrong rows.** A pairwise filter in the database read cache was expanding into a cross product, so a batch lookup could return unrelated rows.
- **Intentional transaction rollbacks** are no longer reported as telemetry errors, and database disconnect errors now propagate out of workers to the supervisor instead of being swallowed.
- **Dropped group invites for members using smart contract wallets.** A transient failure while verifying an ERC-1271/6492 signature was classified as permanent, so the welcome cursor advanced and the invite was skipped for good. Those failures are now retryable and the welcome is reprocessed on the next sync.
- **New installations reliably added to existing groups.** Reconciliation after a welcome now runs as a durable, retried task instead of one inline attempt whose per-group failures were swallowed, so a lost race no longer permanently skips a group.
- **Downgrade resilience for group intents.** Intent rows written by a newer version are now skipped rather than failing every intent query for that group, so downgrading to this version no longer wedges outbound messages in an affected group.
- **Archive export dropped migrated groups.** Groups that had migrated to proposal-based metadata were silently omitted from archives instead of exported.
- **Publish rollback.** A failed publish now resets the intent to `ToPublish` instead of leaving it stranded, and swallowed intent-error causes are preserved in the sync summary rather than replaced with a generic error.
- **Membership adds during identity propagation.** `MissingSequenceId` is now retryable, so adding a member whose identity update has not fully propagated succeeds on retry instead of failing.
- **Groups stuck below the protocol version floor** now recover automatically once the client upgrades past the required floor, instead of staying paused.
- **Reduced log noise** across retry, sync, welcome, and worker paths — steady-state and per-item logs moved from info/error to debug/warn.
