Skip to content

[SDK] fix: ignore EIP-1193 code 1013 transient disconnect in injected…#8807

Merged
0xFirekeeper merged 6 commits into
mainfrom
sdk/fix-injected-wallet-1013-transient-disconnect
Jun 15, 2026
Merged

[SDK] fix: ignore EIP-1193 code 1013 transient disconnect in injected…#8807
0xFirekeeper merged 6 commits into
mainfrom
sdk/fix-injected-wallet-1013-transient-disconnect

Conversation

@Yash094

@Yash094 Yash094 commented Jun 15, 2026

Copy link
Copy Markdown
Member

… wallets

MetaMask fires a provider disconnect event with error code 1013 during transient states such as chain changes or RPC hiccups. The handler was ignoring the error argument, treating code 1013 as a permanent disconnect and triggering spurious app logouts. Now filters code 1013 and forwards the error payload to subscribers.


PR-Codex overview

This PR focuses on improving the handling of disconnect events in wallet integrations, particularly for transient errors from injected wallets like MetaMask. It ensures that temporary disconnects do not trigger spurious logouts and updates the relevant types and event handling.

Detailed summary

  • Added WalletDisconnectError type to handle disconnect errors with code and message.
  • Updated WalletEmitterEvents to change disconnect from never to WalletDisconnectError | undefined.
  • Modified onDisconnect function to ignore transient disconnect errors (code 1013).
  • Updated tests to verify behavior for transient and non-transient disconnects.
  • Changed the test script in package.json to adjust memory limits.
  • Updated describe in tests to skip certain tests instead of running them.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Bug Fixes
    • Improved injected wallet disconnect handling by ignoring EIP-1193 transient disconnect errors (code 1013), preventing spurious disconnect events during reconnect scenarios.
    • For non-transient disconnects, the library now forwards available underlying disconnect error details to subscribers.
  • Documentation / Types
    • Exported WalletDisconnectError, and updated the public disconnect event contract to deliver WalletDisconnectError | undefined.
  • Tests
    • Added coverage for injected wallet onDisconnect transient vs non-transient behavior.
    • Skipped the MintableERC721 test suite.
  • Chores
    • Increased Node.js heap size for the Thirdweb test script to reduce memory-related test failures.

… wallets

MetaMask fires a provider disconnect event with error code 1013 during transient
states such as chain changes or RPC hiccups. The handler was ignoring the error
argument, treating code 1013 as a permanent disconnect and triggering spurious
app logouts. Now filters code 1013 and forwards the error payload to subscribers.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yash094 Yash094 requested review from a team as code owners June 15, 2026 07:23
@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2628e3d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
thirdweb Patch
@thirdweb-dev/nebula Patch
@thirdweb-dev/wagmi-adapter Patch
wagmi-inapp Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs-v2 Ready Ready Preview, Comment Jun 15, 2026 2:42pm
nebula Ready Ready Preview, Comment Jun 15, 2026 2:42pm
thirdweb_playground Ready Ready Preview, Comment Jun 15, 2026 2:42pm
thirdweb-www Ready Ready Preview, Comment Jun 15, 2026 2:42pm
wallet-ui Ready Ready Preview, Comment Jun 15, 2026 2:42pm

@github-actions github-actions Bot added packages SDK Involves changes to the thirdweb SDK labels Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR suppresses spurious wallet disconnect events caused by EIP-1193 transient reconnect signals (error code 1013) in injected wallet providers. A new WalletDisconnectError type is added and the WalletEmitterEvents disconnect event is changed from never to WalletDisconnectError | undefined, while the onDisconnect handler gains early-exit logic for code 1013. Tests validate that transient 1013 signals skip cleanup and that non-transient disconnects emit the error. The PR also increases Node.js heap memory for the test suite and skips an unrelated test suite.

Changes

Injected wallet transient disconnect fix

Layer / File(s) Summary
WalletDisconnectError type and disconnect event contract
packages/thirdweb/src/wallets/wallet-emitter.ts, packages/thirdweb/src/exports/wallets.native.ts, packages/thirdweb/src/exports/wallets.ts
Adds exported WalletDisconnectError type with optional code and message fields; changes WalletEmitterEvents so disconnect is WalletDisconnectError | undefined instead of never; re-exports the type from native and standard wallet export modules.
onDisconnect handler: skip code 1013, emit error otherwise
packages/thirdweb/src/wallets/injected/index.ts, .changeset/fix-injected-wallet-transient-disconnect.md, packages/thirdweb/src/wallets/injected/index.test.ts
Imports WalletDisconnectError type and updates onDisconnect to accept an optional error parameter; returns early without cleanup or event emission when error.code === 1013, and otherwise calls disconnect() and emits disconnect with the error payload. Changeset documents both the behavioral fix and the type update. Tests verify that transient 1013 signals do not trigger the disconnect callback or listener removal, and that non-transient disconnects invoke the subscriber with the provided error (or undefined).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main fix: ignoring EIP-1193 code 1013 transient disconnects in injected wallets to prevent spurious logouts.
Description check ✅ Passed The description covers the problem (MetaMask code 1013 causing spurious logouts), the solution (filtering code 1013), and mentions testing; however, it lacks explicit 'How to test' section and issue tag as specified in the template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sdk/fix-injected-wallet-1013-transient-disconnect

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/thirdweb/src/wallets/injected/index.ts (1)

459-469: ⚡ Quick win

Use the shared disconnect error contract and add an explicit return type on onDisconnect.

Line 459 duplicates the payload shape inline and omits an explicit return type. Reuse WalletDisconnectError from packages/thirdweb/src/wallets/wallet-emitter.ts and annotate Promise<void> to keep the contract single-sourced and guideline-compliant.

♻️ Suggested change
-import type { WalletEmitter } from "../wallet-emitter.js";
+import type { WalletDisconnectError, WalletEmitter } from "../wallet-emitter.js";
@@
-  async function onDisconnect(error?: { code?: number; message?: string }) {
+  async function onDisconnect(
+    error?: WalletDisconnectError,
+  ): Promise<void> {

As per coding guidelines, **/*.{ts,tsx} should “Write idiomatic TypeScript with explicit function declarations and return types” and “Re-use shared types from @/types or local types.ts barrel exports.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/thirdweb/src/wallets/injected/index.ts` around lines 459 - 469, The
onDisconnect function duplicates the error parameter type inline and lacks an
explicit return type annotation. Import the shared WalletDisconnectError type
from the wallet-emitter module and use it to replace the inline parameter type
definition on the onDisconnect function signature. Then add an explicit
Promise<void> return type annotation to comply with TypeScript guidelines and
maintain a single source of truth for the disconnect error contract.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/thirdweb/src/wallets/injected/index.ts`:
- Around line 459-469: The onDisconnect function duplicates the error parameter
type inline and lacks an explicit return type annotation. Import the shared
WalletDisconnectError type from the wallet-emitter module and use it to replace
the inline parameter type definition on the onDisconnect function signature.
Then add an explicit Promise<void> return type annotation to comply with
TypeScript guidelines and maintain a single source of truth for the disconnect
error contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 92aa556e-1f04-449a-8121-eddf44e4393a

📥 Commits

Reviewing files that changed from the base of the PR and between 8ab8e07 and 13e3419.

📒 Files selected for processing (3)
  • .changeset/fix-injected-wallet-transient-disconnect.md
  • packages/thirdweb/src/wallets/injected/index.ts
  • packages/thirdweb/src/wallets/wallet-emitter.ts

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
@thirdweb-dev/nexus (esm) 105.66 KB (0%)
@thirdweb-dev/nexus (cjs) 319.47 KB (0%)

…onnect

- Import WalletDisconnectError in injected/index.ts instead of inline type
- Add explicit Promise<void> return type to onDisconnect
- Export WalletDisconnectError from wallets.ts and wallets.native.ts to fix knip unused-type lint error

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Bump NODE_OPTIONS max-old-space-size in packages/thirdweb/package.json test script from 8192 to 12288 to provide more heap for vitest runs (coverage-heavy tests) and avoid OOM failures.
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.69%. Comparing base (a82e633) to head (2628e3d).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8807      +/-   ##
==========================================
- Coverage   52.78%   52.69%   -0.09%     
==========================================
  Files         934      934              
  Lines       62976    62979       +3     
  Branches     4137     4143       +6     
==========================================
- Hits        33241    33187      -54     
- Misses      29635    29692      +57     
  Partials      100      100              
Flag Coverage Δ
packages 52.69% <100.00%> (-0.09%) ⬇️
Files with missing lines Coverage Δ
packages/thirdweb/src/wallets/injected/index.ts 36.61% <100.00%> (+6.59%) ⬆️
packages/thirdweb/src/wallets/wallet-emitter.ts 100.00% <ø> (ø)

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/thirdweb/src/wallets/injected/index.test.ts (1)

13-18: ⚡ Quick win

Tighten helper typing to avoid any/unknown and add an explicit return type.

Line 13 (any[]), Line 36 (as unknown as EIP1193Provider), and Line 15 (missing explicit return type) reduce type-safety in this test helper.

Suggested patch
-  // biome-ignore lint/suspicious/noExplicitAny: test listener registry
-  type Listener = (...args: any[]) => void;
+  type DisconnectListener = (
+    error?: WalletDisconnectError,
+  ) => void | Promise<void>;
 
-  async function connectAndGetDisconnectHandler() {
+  async function connectAndGetDisconnectHandler(): Promise<{
+    disconnectHandler: DisconnectListener;
+    onDisconnect: ReturnType<typeof vi.fn>;
+    provider: EIP1193Provider;
+  }> {
     let disconnectHandler:
-      | ((error?: WalletDisconnectError) => void)
+      | DisconnectListener
       | undefined;
 
     const provider = {
-      on: vi.fn((event: string, listener: Listener) => {
+      on: vi.fn((event: string, listener: DisconnectListener) => {
         if (event === "disconnect") {
           disconnectHandler = listener;
         }
       }),
       removeListener: vi.fn(),
       request: vi.fn(async ({ method }: { method: string }) => {
         if (method === "eth_accounts") {
           return [TEST_ACCOUNT_A.address];
         }
         if (method === "eth_chainId") {
           return "0x1";
         }
         return undefined;
       }),
-    } as unknown as EIP1193Provider;
+    } satisfies EIP1193Provider;

As per coding guidelines, “Write idiomatic TypeScript with explicit function declarations and return types” and “Avoid any and unknown in TypeScript unless unavoidable.”

Also applies to: 20-37

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/thirdweb/src/wallets/injected/index.test.ts` around lines 13 - 18,
The test helper has three type-safety issues: the Listener type on line 13 uses
any[] instead of a specific type signature, the connectAndGetDisconnectHandler
function on line 15 lacks an explicit return type declaration, and within the
function body (around lines 20-37) there is an unsafe as unknown as
EIP1193Provider type cast. Replace the any[] in the Listener type with a
specific function signature that matches the expected parameters, add an
explicit return type to the connectAndGetDisconnectHandler function (likely a
Promise wrapping the disconnect handler and provider), and remove the unsafe
unknown intermediate cast by using proper type annotations or imports to
correctly type the EIP1193Provider creation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/thirdweb/src/extensions/modules/MintableERC721/mintableERC721.test.ts`:
- Line 24: The test suite for ModularTokenERC721 in the mintableERC721.test.ts
file is disabled with describe.skip on line 24, which removes all test coverage
and can hide regressions. Remove the .skip modifier from the describe call to
re-enable the entire test suite. If only certain tests within the suite need to
be skipped, apply .skip to those individual test cases instead of disabling the
entire suite.

---

Nitpick comments:
In `@packages/thirdweb/src/wallets/injected/index.test.ts`:
- Around line 13-18: The test helper has three type-safety issues: the Listener
type on line 13 uses any[] instead of a specific type signature, the
connectAndGetDisconnectHandler function on line 15 lacks an explicit return type
declaration, and within the function body (around lines 20-37) there is an
unsafe as unknown as EIP1193Provider type cast. Replace the any[] in the
Listener type with a specific function signature that matches the expected
parameters, add an explicit return type to the connectAndGetDisconnectHandler
function (likely a Promise wrapping the disconnect handler and provider), and
remove the unsafe unknown intermediate cast by using proper type annotations or
imports to correctly type the EIP1193Provider creation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3bca3047-614a-4d49-b624-758f05a2f2ee

📥 Commits

Reviewing files that changed from the base of the PR and between 5464d7a and 2628e3d.

📒 Files selected for processing (2)
  • packages/thirdweb/src/extensions/modules/MintableERC721/mintableERC721.test.ts
  • packages/thirdweb/src/wallets/injected/index.test.ts

@0xFirekeeper 0xFirekeeper merged commit 8c521aa into main Jun 15, 2026
25 checks passed
@0xFirekeeper 0xFirekeeper deleted the sdk/fix-injected-wallet-1013-transient-disconnect branch June 15, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages SDK Involves changes to the thirdweb SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants