const shortUrlAside = document.getElementById('short-url-aside');
const statusOutput = document.getElementById('status');
const form = document.querySelector('form');
+const walletPicker = document.getElementById('wallet-picker');
const notification = document.getElementById('notification');
+const wallets = [];
// Helper function to call the balanceOf function on an address to check if it's eligible to create
// custom short URLs. The same logic is executed on the backend to independently validate on server-side.
}
}
-if (window.ethereum !== undefined) {
- // User switches account manually in wallet
- ethereum?.addListener?.('accountsChanged', setAccount) ?? ethereum.on('accountsChanged', setAccount);
-}
-
connectButton.addEventListener('click', () => {
- if (window.ethereum !== undefined) {
- ethereum
- .request({ method: 'eth_requestAccounts' })
- .then(setAccount);
+ if (wallets.length <= 1 && window.ethereum !== undefined) {
+ ethereum?.addListener?.('accountsChanged', setAccount) ?? ethereum.on('accountsChanged', setAccount); // Handle user switching account after connecting
+ ethereum.request({ method: 'eth_requestAccounts' }).then(setAccount); // Set initial address
+ }
+ else if (wallets.length > 0) {
+ walletPicker.showModal();
+ const walletList = walletPicker.querySelector('ul');
+ walletList.innerHTML = '';
+ for (const wallet of wallets) {
+ walletList.insertAdjacentHTML('beforeend', `<li><button data-uuid="${wallet.info.uuid}">${wallet.info.name}</button></li>`)
+ }
+ // The rest of logic is handled in the wallet picker "click" event listener
}
else {
notification.show();
infoButton.addEventListener('click', () => {
infoDialog.showModal();
});
+
+// EIP-6963: Multi Injected Provider Discovery
+// https://eips.ethereum.org/EIPS/eip-6963
+window.addEventListener('eip6963:announceProvider', e => wallets.push(e.detail));
+window.dispatchEvent(new Event('eip6963:requestProvider'));
+
+// Capture bubbled-up "click" events from the wallet buttons inside the picker dialog.
+// Listening for the "click" event instead of "close" to capture the specific button element.
+walletPicker.addEventListener('click', e => {
+ if (e.target.dataset?.uuid === undefined) {
+ return;
+ }
+ globalThis.ethereum = wallets.find(wallet => wallet.info.uuid === e.target.dataset.uuid)?.provider ?? globalThis.ethereum;
+ ethereum?.addListener?.('accountsChanged', setAccount) ?? ethereum.on('accountsChanged', setAccount);
+ ethereum.request({ method: 'eth_requestAccounts' }).then(setAccount);
+});
align-self: center;
}
+#wallet-picker, #notification {
+ border-radius: 16px;
+ border: 2px solid var(--primary-strongest);
+}
+
+#wallet-picker::backdrop {
+ filter: blur(4px);
+ background-color: var(--primary-transparent);
+}
+
+#wallet-picker ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+}
+
+#wallet-picker li {
+ background-color: var(--secondary-transparent);
+ border: 2px solid var(--primary-stronger);
+ border-radius: 16px;
+ margin: 4px;
+ transition: filter 400ms, background-color 400ms;
+}
+
+#wallet-picker :is(li:hover, li:focus-within) {
+ background-color: var(--secondary);
+ filter: brightness(115%);
+ transition: filter 200ms, background-color 200ms;
+}
+
+#wallet-picker li button {
+ inline-size: 100%;
+ font-weight: 700;
+ font-size: 1.5rem;
+ padding: 36px;
+}
+
+#wallet-picker p {
+ margin: 0;
+ font-weight: 700;
+ font-size: 1.5rem;
+}
+
#notification {
position: fixed;
bottom: 16px;
- border-radius: 16px;
- border: 2px solid var(--primary-strongest);
}
#notification>form {