Skip to content

Fix: Initialize Web3 with injected provider when MetaMask is available#89

Open
Rav1Chauhan wants to merge 1 commit intoDjedAlliance:mainfrom
Rav1Chauhan:fix/metamask-web3-init2
Open

Fix: Initialize Web3 with injected provider when MetaMask is available#89
Rav1Chauhan wants to merge 1 commit intoDjedAlliance:mainfrom
Rav1Chauhan:fix/metamask-web3-init2

Conversation

@Rav1Chauhan
Copy link

@Rav1Chauhan Rav1Chauhan commented Feb 23, 2026

Addressed Issues:

Fixes #63
This PR fixes the Web3 initialization logic inside the SDK.

Previously, the SDK detected window.ethereum (MetaMask) but still instantiated Web3 using a static HttpProvider(URI). As a result, state-changing transactions did not trigger the MetaMask popup because the injected provider was never used.

Changes Made

Updated getWeb3() to initialize Web3 using:
new Web3(window.ethereum)
when window.ethereum is available.
Added eth_requestAccounts to properly request wallet access.

Preserved fallback behavior to HttpProvider(URI) when no injected provider exists.

Result

MetaMask popup now appears for state-changing transactions.

Transactions are correctly signed using the injected provider.

No breaking changes introduced.

Fallback behavior remains intact.

Additional Notes:

Checklist

  • [ x] My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • [x ] My code follows the project's code style and conventions.
  • If applicable, I have made corresponding changes or additions to the documentation.
  • If applicable, I have made corresponding changes or additions to tests.
  • [ x] My changes generate no new warnings or errors.
  • I have joined the Stability Nexus's Discord server and I will share a link to this PR with the project maintainers there.
  • [ x] I have read the Contribution Guidelines.
  • [x ] Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.

⚠️ AI Notice - Important!

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.

Summary by CodeRabbit

  • Refactor

    • Enhanced Web3 provider initialization with improved browser Ethereum provider detection and RPC fallback mechanism. Parameter name updated.
  • Chores

    • Updated .gitignore to exclude build output.

@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

📝 Walkthrough

Walkthrough

The pull request refactors the getWeb3 function to prioritize detecting and using a browser's Ethereum provider (window.ethereum) when available, with fallback to RPC-based Web3 instantiation. The function signature changes from Promise-based to async, the parameter is renamed from BLOCKCHAIN_URI to URI, and account access is now requested via eth_requestAccounts. Additionally, dist/ is added to the .gitignore.

Changes

Cohort / File(s) Summary
Web3 Provider Initialization
djed-sdk/src/web3.js
Rewrote getWeb3 as async function to detect and use browser Ethereum provider (window.ethereum) when available; falls back to HttpProvider with provided URI. Parameter renamed from BLOCKCHAIN_URI to URI. Requests account access via eth_requestAccounts and improves error handling with logging and rethrow pattern.
Git Configuration
stablepay-sdk/.gitignore
Added dist/ directory to ignore list, preventing build output from version control.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A provider was lost in the code so deep,
While Metamask danced where browsers sleep,
Now Web3 springs forth with a browser-first call,
And fallback paths catch us, preventing a fall!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive The addition of dist/ to .gitignore in stablepay-sdk is a minor, unrelated change to build output configuration; the primary change to djed-sdk/src/web3.js is fully in scope. Clarify why dist/ was added to .gitignore; if unrelated to issue #63, consider moving to a separate PR or document the rationale for inclusion.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: initializing Web3 with the injected MetaMask provider when available, which aligns with the core objective.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #63: detects window.ethereum, initializes Web3 with new Web3(window.ethereum), requests account access via eth_requestAccounts, and maintains HttpProvider fallback.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
djed-sdk/src/web3.js (1)

6-9: Consider requesting accounts before constructing the Web3 instance.

The current order creates a Web3 instance on line 6 and then requests account access on line 9. If the user denies, the Web3 instance is silently garbage-collected — functionally harmless, but inverted from the natural read order (access → instance). Flipping the two ensures Web3 is only constructed when a grant is confirmed.

♻️ Suggested reorder
-      const web3 = new Web3(window.ethereum);
-
-      // Request account access (important)
-      await window.ethereum.request({ method: "eth_requestAccounts" });
-
-      return web3;
+      // Request account access before constructing the instance
+      await window.ethereum.request({ method: "eth_requestAccounts" });
+
+      return new Web3(window.ethereum);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@djed-sdk/src/web3.js` around lines 6 - 9, Request accounts with
window.ethereum.request({ method: "eth_requestAccounts" }) before constructing
the Web3 instance so Web3 is only created after permission is granted; move the
await window.ethereum.request call to before const web3 = new
Web3(window.ethereum), and ensure any rejection from window.ethereum.request is
handled (e.g., try/catch or .catch) so you only call new Web3(window.ethereum)
on success.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@djed-sdk/src/web3.js`:
- Around line 12-14: The catch block currently logs a hardcoded "User denied
account access" for all errors; update the catch to inspect the error (e.g.,
check error.code === 4001) and only log the user-rejection message when that
code is present, otherwise log a generic or the actual error (include
error.message or error) to avoid misleading output; locate the catch around the
window.ethereum.request (or provider request) call and replace the unconditional
console.error("User denied account access", error) with a conditional log based
on error.code.
- Line 19: The getWeb3 function currently constructs new
Web3.providers.HttpProvider(URI) without validating URI, which can pass
undefined and produce opaque provider errors; update getWeb3 to validate the URI
parameter (ensure it's a non-empty string and a valid URL scheme like
http/https) before creating a new HttpProvider, and if invalid or missing (and
window.ethereum is absent) throw or return a clear error (e.g., throw new
Error('Missing or invalid RPC URI')) so callers get an immediate, descriptive
failure instead of opaque provider-level errors; locate the check around
getWeb3, the URI variable, and the Web3.providers.HttpProvider instantiation to
implement this guard.
- Around line 3-19: The published bundle still contains the old getWeb3
implementation, so rebuild and overwrite the dist artifacts with the fixed
source: run the project build step (so dist/esm/index.js and dist/umd/index.js
are regenerated) ensuring the exported getWeb3 function in the dist matches the
source that uses window.ethereum and eth_requestAccounts; verify package.json's
"main" and "module" still point to dist/umd/index.js and dist/esm/index.js and
then commit the regenerated files (or update the build/publish pipeline to run
the build before publishing) so consumers receive the corrected implementation.

---

Nitpick comments:
In `@djed-sdk/src/web3.js`:
- Around line 6-9: Request accounts with window.ethereum.request({ method:
"eth_requestAccounts" }) before constructing the Web3 instance so Web3 is only
created after permission is granted; move the await window.ethereum.request call
to before const web3 = new Web3(window.ethereum), and ensure any rejection from
window.ethereum.request is handled (e.g., try/catch or .catch) so you only call
new Web3(window.ethereum) on success.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 509e7d3 and 685a668.

⛔ Files ignored due to path filters (3)
  • stablepay-sdk/dist/umd/index.js.map is excluded by !**/dist/**, !**/*.map
  • stablepay-sdk/dist/umd/test.html is excluded by !**/dist/**
  • stablepay-sdk/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • djed-sdk/src/web3.js
  • stablepay-sdk/.gitignore

Comment on lines +3 to +19
export const getWeb3 = async (URI) => {
if (typeof window !== "undefined" && window.ethereum) {
try {
const web3 = new Web3(window.ethereum);

// Request account access (important)
await window.ethereum.request({ method: "eth_requestAccounts" });

return web3;
} catch (error) {
console.error("User denied account access", error);
throw error;
}
});
}

// Fallback to RPC
return new Web3(new Web3.providers.HttpProvider(URI));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 1. Check if djed-sdk/dist files are tracked by git
echo "=== Checking if djed-sdk/dist files are tracked by git ==="
git -C djed-sdk ls-files dist/ 2>/dev/null | head -20

# 2. Confirm what entrypoints package.json exposes
echo ""
echo "=== Checking djed-sdk/package.json entrypoints ==="
fd "package.json" djed-sdk --max-depth 2 --exec cat {}

# 3. Show the stale provider logic still in dist
echo ""
echo "=== Searching for BLOCKCHAIN_URI or old Web3 logic in dist ==="
rg -n "BLOCKCHAIN_URI\|new Web3\(BLOCKCHAIN_URI" djed-sdk/dist/ 2>/dev/null || echo "No matches found"

Repository: DjedAlliance/StablePay

Length of output: 836


🏁 Script executed:

#!/bin/bash
# Check the actual content of dist files to see if they're truly stale
echo "=== Content of dist/esm/index.js ==="
cat djed-sdk/dist/esm/index.js

echo ""
echo "=== Content of dist/umd/index.js ==="
cat djed-sdk/dist/umd/index.js

# Also check git history to see when dist was last updated
echo ""
echo "=== Recent git commits touching dist files ==="
git log --oneline -n 10 -- djed-sdk/dist/

Repository: DjedAlliance/StablePay

Length of output: 50378


Dist bundles in djed-sdk/dist/ are stale and ship the old broken implementation.

The dist files (djed-sdk/dist/esm/index.js and djed-sdk/dist/umd/index.js) still contain the original broken getWeb3 implementation that directly passes BLOCKCHAIN_URI to Web3(BLOCKCHAIN_URI), whereas the fixed source code properly requests account access and uses window.ethereum. Since package.json points to these dist files as the main entrypoints ("main": "dist/umd/index.js", "module": "dist/esm/index.js"), consumers will receive the broken code from the published package regardless of this source fix.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@djed-sdk/src/web3.js` around lines 3 - 19, The published bundle still
contains the old getWeb3 implementation, so rebuild and overwrite the dist
artifacts with the fixed source: run the project build step (so
dist/esm/index.js and dist/umd/index.js are regenerated) ensuring the exported
getWeb3 function in the dist matches the source that uses window.ethereum and
eth_requestAccounts; verify package.json's "main" and "module" still point to
dist/umd/index.js and dist/esm/index.js and then commit the regenerated files
(or update the build/publish pipeline to run the build before publishing) so
consumers receive the corrected implementation.

Comment on lines +12 to +14
} catch (error) {
console.error("User denied account access", error);
throw error;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Catch-all error message misleadingly implies the error is always a user denial.

"User denied account access" is only accurate for the EIP-1193 user-rejection code (4001). The same catch block fires for any runtime error (e.g., window.ethereum.request missing, unexpected provider failures). Either narrow the message or inspect the error code before logging.

🛡️ Suggested fix
-      console.error("User denied account access", error);
+      console.error("Failed to request account access", error);

Or, if you want to preserve the specific message for user rejections:

     } catch (error) {
+      if (error.code === 4001) {
+        console.error("User denied account access", error);
+      } else {
         console.error("User denied account access", error);
+      }
       throw error;
     }

Simplified:

-      console.error("User denied account access", error);
+      const msg = error?.code === 4001
+        ? "User denied account access"
+        : "Failed to initialize wallet provider";
+      console.error(msg, error);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
console.error("User denied account access", error);
throw error;
} catch (error) {
const msg = error?.code === 4001
? "User denied account access"
: "Failed to initialize wallet provider";
console.error(msg, error);
throw error;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@djed-sdk/src/web3.js` around lines 12 - 14, The catch block currently logs a
hardcoded "User denied account access" for all errors; update the catch to
inspect the error (e.g., check error.code === 4001) and only log the
user-rejection message when that code is present, otherwise log a generic or the
actual error (include error.message or error) to avoid misleading output; locate
the catch around the window.ethereum.request (or provider request) call and
replace the unconditional console.error("User denied account access", error)
with a conditional log based on error.code.

}

// Fallback to RPC
return new Web3(new Web3.providers.HttpProvider(URI));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

URI is not validated before being passed to HttpProvider.

If a caller invokes getWeb3() without a URI argument and window.ethereum is absent, new Web3.providers.HttpProvider(undefined) is constructed silently. All subsequent RPC calls will fail with opaque provider-level errors rather than a clear early-rejection.

🛡️ Suggested guard
+  if (!URI) {
+    throw new Error("No injected provider found and no fallback URI supplied.");
+  }
   // Fallback to RPC
   return new Web3(new Web3.providers.HttpProvider(URI));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return new Web3(new Web3.providers.HttpProvider(URI));
if (!URI) {
throw new Error("No injected provider found and no fallback URI supplied.");
}
// Fallback to RPC
return new Web3(new Web3.providers.HttpProvider(URI));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@djed-sdk/src/web3.js` at line 19, The getWeb3 function currently constructs
new Web3.providers.HttpProvider(URI) without validating URI, which can pass
undefined and produce opaque provider errors; update getWeb3 to validate the URI
parameter (ensure it's a non-empty string and a valid URL scheme like
http/https) before creating a new HttpProvider, and if invalid or missing (and
window.ethereum is absent) throw or return a clear error (e.g., throw new
Error('Missing or invalid RPC URI')) so callers get an immediate, descriptive
failure instead of opaque provider-level errors; locate the check around
getWeb3, the URI variable, and the Web3.providers.HttpProvider instantiation to
implement this guard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Metamask Provider Ignored in StablePay/djed-sdk/src/web3.js

1 participant