Conversation
*With better explanations and comments removes where not needed
|
Team its been a very intresting turn of events lately, i appologize for dropping the ball and im the one creating all the infura and coinbase security alerts that dont result to anything, I could use help getting all accounts connected back together and those who choose to help once funds are released back to me not suspended i will greatly accomodate all who do |
Co-authored-by: SumnersMetaverse <207414489+SumnersMetaverse@users.noreply.github.com>
Co-authored-by: SumnersMetaverse <207414489+SumnersMetaverse@users.noreply.github.com>
…n-documentation Fixed markdown code fence syntax errors in wallet connection guide
There was a problem hiding this comment.
Pull request overview
Updates the “Connect to MetaMask” documentation to expand and modernize the EIP-6963 connection guidance, including Vite-based examples and additional library options.
Changes:
- Reworks the intro content around EIP-6963/EIP-1193 and updates the third-party library list.
- Adds a Vite-focused walkthrough with tabbed Vanilla TypeScript and React + TypeScript example snippets.
- Expands explanatory text around provider discovery, connection, and helper utilities.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -1,204 +1,368 @@ | |||
| --- | |||
| description: Connect to MetaMask via EIP-6963. | |||
| Description: Connect to MetaMask via EIP-6963. | |||
There was a problem hiding this comment.
The front matter key Description is capitalized. Other docs in this section use description: (lowercase), and Docusaurus front matter parsing may ignore the capitalized key, losing the page description. Rename it back to description:.
| Description: Connect to MetaMask via EIP-6963. | |
| description: Connect to MetaMask via EIP-6963. |
| #### Create a Vite project with the EIP-6963 interfaces and types | ||
|
|
||
| ### Steps | ||
| This page will walk you through two examples using "ViteJS and Vanilla TypScript" and "ViteJS and React & TypeScript". Choose your adventure! |
There was a problem hiding this comment.
Typo in the example list text: "TypScript" should be "TypeScript".
| This page will walk you through two examples using "ViteJS and Vanilla TypScript" and "ViteJS and React & TypeScript". Choose your adventure! | |
| This page will walk you through two examples using "ViteJS and Vanilla TypeScript" and "ViteJS and React & TypeScript". Choose your adventure! |
| <h2>{userAccount ? "" : "No "}Wallet Selected</h2> | ||
| {userAccount && |
There was a problem hiding this comment.
selectedWallet is optional, but this render path dereferences selectedWallet.info... without a null check. Gate this UI on selectedWallet being set (or use optional chaining) rather than only userAccount, to avoid TS errors and potential runtime exceptions.
| <h2>{userAccount ? "" : "No "}Wallet Selected</h2> | |
| {userAccount && | |
| <h2>{userAccount && selectedWallet ? "" : "No "}Wallet Selected</h2> | |
| {userAccount && selectedWallet && |
| <TabItem value= "DiscoverWalletProviders.tsx"> | ||
|
|
||
| ```tsx title="DiscoverWalletProviders.tsx" | ||
| ```ts title="src/components/DiscoverWalletProviders.tsx" |
There was a problem hiding this comment.
This code fence is labeled as ts, but the file is .tsx and contains JSX. Use tsx as the fence language for accurate highlighting and copy/paste expectations.
| export function listProviders(element: HTMLDivElement) { | ||
| window.addEventListener('eip6963:announceProvider', | ||
| (event: EIP6963AnnounceProviderEvent) => { | ||
| const button = document.createElement('button') | ||
|
|
There was a problem hiding this comment.
listProviders appends a button for every eip6963:announceProvider event but doesn’t deduplicate by provider UUID. This can create duplicate buttons (e.g., if the event fires multiple times or if listProviders is invoked more than once). Track seen UUIDs and skip/replace existing entries.
| <TabItem value="vite-env.d.ts"> | ||
|
|
||
| ```typescript title="src/vite-env.d.ts" | ||
| /// <reference types= "vite/client"/> |
There was a problem hiding this comment.
The TypeScript triple-slash reference directive is malformed (types= "vite/client" and missing space before closing />). Use the standard /// <reference types="vite/client" /> form so readers can paste it without TS directive parsing issues.
| /// <reference types= "vite/client"/> | |
| /// <reference types="vite/client" /> |
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `app` and sets its `innerHTML`. We need to include a basic HMTL structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | ||
|
|
||
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using a'ppendChild` to add each button within the `div` with the `id` of `providerButtons` |
There was a problem hiding this comment.
There are multiple typos/formatting issues in this paragraph that will confuse readers and break inline code formatting ("HMTL" -> "HTML", and a'ppendChild is misspelled and missing an opening backtick). Please correct the spelling and ensure inline code spans are properly delimited.
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `app` and sets its `innerHTML`. We need to include a basic HMTL structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | |
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using a'ppendChild` to add each button within the `div` with the `id` of `providerButtons` | |
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `#app` and sets its `innerHTML`. We need to include a basic HTML structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | |
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using `appendChild` to add each button within the `div` with the `id` of `providerButtons`. |
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `app` and sets its `innerHTML`. We need to include a basic HMTL structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | ||
|
|
||
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using a'ppendChild` to add each button within the `div` with the `id` of `providerButtons` |
There was a problem hiding this comment.
The explanation says the selector is app, but the code uses document.querySelector('#app') (an id selector). Update the text to reference #app so it matches the snippet and avoids confusing readers about CSS selectors.
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `app` and sets its `innerHTML`. We need to include a basic HMTL structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | |
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using a'ppendChild` to add each button within the `div` with the `id` of `providerButtons` | |
| The `querySelector` finds and returns the first HTML element that matches the CSS selector `#app` and sets its `innerHTML`. We need to include a basic HTML structure with an inner `div` to inject a list of buttons, each representing a wallet provider we have discovered. | |
| The `listProviders` function is what we will create next, and we need to pass an argument which represents the `div` element. This function will be responsible for connecting to the specific provider using `eth_requestAccounts` and then using `appendChild` to add each button within the `div` with the `id` of `providerButtons`. |
| const accounts = await providerWithInfo.provider.request({ | ||
| method: 'eth_requestAccounts' | ||
| }) | ||
|
|
||
| setSelectedWallet(providerWithInfo) | ||
| setUserAccount(accounts?.[0]) |
There was a problem hiding this comment.
In this example, provider.request(...) is typed earlier as returning Promise<unknown>, but the result is later treated like an accounts array. Cast/define the return type as string[] and only set state when at least one address is returned.
| const accounts = await providerWithInfo.provider.request({ | |
| method: 'eth_requestAccounts' | |
| }) | |
| setSelectedWallet(providerWithInfo) | |
| setUserAccount(accounts?.[0]) | |
| const accounts = await providerWithInfo.provider.request({ | |
| method: 'eth_requestAccounts' | |
| }) as string[] | |
| if (accounts && accounts.length > 0) { | |
| setSelectedWallet(providerWithInfo) | |
| setUserAccount(accounts[0]) | |
| } |
|
|
||
| button.innerHTML = ` | ||
| <img src="${event.detail.info.icon}" alt="${event.detail.info.name}" /> | ||
| <div>${event.detail.info.name}</div>` | ||
|
|
There was a problem hiding this comment.
The button.innerHTML assignment is building an HTML string with event.detail.info.icon and event.detail.info.name interpolated directly into the markup. Because EIP-6963 provider metadata (or any code that can dispatch an eip6963:announceProvider event) is effectively untrusted, a malicious provider could supply values that break out of the attribute or element context and inject arbitrary HTML/JavaScript (DOM XSS). To avoid this, construct the img and text nodes using DOM APIs (for example, document.createElement and textContent) or otherwise ensure these values are safely escaped before inserting them into the DOM.
| button.innerHTML = ` | |
| <img src="${event.detail.info.icon}" alt="${event.detail.info.name}" /> | |
| <div>${event.detail.info.name}</div>` | |
| const img = document.createElement('img') | |
| img.src = event.detail.info.icon | |
| img.alt = event.detail.info.name | |
| const nameDiv = document.createElement('div') | |
| nameDiv.textContent = event.detail.info.name | |
| button.appendChild(img) | |
| button.appendChild(nameDiv) |
Description
Issue(s) fixed
Fixes #
Preview
Checklist
Complete this checklist before merging your PR: