|
|
@@ -0,0 +1,253 @@
|
|
|
+// ==UserScript==
|
|
|
+// @name Web3网络快速切换器
|
|
|
+// @namespace http://tampermonkey.net/
|
|
|
+// @version 1.1
|
|
|
+// @description 在页面上添加下拉框快速切换Web3钱包网络
|
|
|
+// @author You
|
|
|
+// @match *://*/*
|
|
|
+// @grant GM_notification
|
|
|
+// ==/UserScript==
|
|
|
+
|
|
|
+(function() {
|
|
|
+ 'use strict';
|
|
|
+
|
|
|
+ // 配置:预设的网络列表(目前只有Monad测试网,您可以自行添加)
|
|
|
+ const networks = [
|
|
|
+ { name: "Monad Testnet", chainId: "0x4a", rpcUrls: ["https://testnet.monad.xyz"] }
|
|
|
+ // 您可以在这里添加其他网络,格式如下:
|
|
|
+ // { name: "网络名称", chainId: "网络ID", rpcUrls: ["RPC URL"] },
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 创建样式
|
|
|
+ const style = document.createElement('style');
|
|
|
+ style.textContent = `
|
|
|
+ .web3-network-switcher {
|
|
|
+ position: fixed;
|
|
|
+ top: 20px;
|
|
|
+ right: 20px;
|
|
|
+ z-index: 9999;
|
|
|
+ padding: 10px;
|
|
|
+ background-color: rgba(255, 255, 255, 0.95);
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
|
+ font-family: Arial, sans-serif;
|
|
|
+ min-width: 200px;
|
|
|
+ }
|
|
|
+ .web3-network-switcher label {
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ .web3-network-switcher select {
|
|
|
+ width: 100%;
|
|
|
+ padding: 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ background-color: white;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .web3-network-switcher select:focus {
|
|
|
+ outline: none;
|
|
|
+ border-color: #4a90e2;
|
|
|
+ box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
|
|
|
+ }
|
|
|
+ .web3-network-switcher .status {
|
|
|
+ margin-top: 8px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ .web3-network-switcher .toggle {
|
|
|
+ position: absolute;
|
|
|
+ top: 5px;
|
|
|
+ right: 5px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ .web3-network-switcher.collapsed {
|
|
|
+ width: auto;
|
|
|
+ min-width: auto;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+ .web3-network-switcher.collapsed select,
|
|
|
+ .web3-network-switcher.collapsed label,
|
|
|
+ .web3-network-switcher.collapsed .status {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ `;
|
|
|
+ document.head.appendChild(style);
|
|
|
+
|
|
|
+ // 等待页面加载完成后执行
|
|
|
+ setTimeout(init, 2000);
|
|
|
+
|
|
|
+ function init() {
|
|
|
+ // 如果页面已存在切换器,先移除
|
|
|
+ const existing = document.getElementById('web3-network-switcher');
|
|
|
+ if (existing) existing.remove();
|
|
|
+
|
|
|
+ // 重新初始化
|
|
|
+ if (typeof window.ethereum !== 'undefined') {
|
|
|
+ // 这里需要执行createNetworkSelector函数
|
|
|
+ // 可能需要将函数改为全局可访问
|
|
|
+ console.log('Web3钱包已检测到');
|
|
|
+ } else {
|
|
|
+ console.log('未检测到Web3钱包');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建网络选择器
|
|
|
+ createNetworkSelector();
|
|
|
+ }
|
|
|
+
|
|
|
+ function createNetworkSelector() {
|
|
|
+ // 如果已存在,先移除
|
|
|
+ const existing = document.getElementById('web3-network-switcher');
|
|
|
+ if (existing) existing.remove();
|
|
|
+
|
|
|
+ // 创建容器
|
|
|
+ const container = document.createElement('div');
|
|
|
+ container.className = 'web3-network-switcher';
|
|
|
+ container.id = 'web3-network-switcher';
|
|
|
+
|
|
|
+ // 创建折叠按钮
|
|
|
+ const toggleBtn = document.createElement('div');
|
|
|
+ toggleBtn.className = 'toggle';
|
|
|
+ toggleBtn.textContent = '−';
|
|
|
+ toggleBtn.title = '折叠/展开';
|
|
|
+ toggleBtn.onclick = function() {
|
|
|
+ container.classList.toggle('collapsed');
|
|
|
+ toggleBtn.textContent = container.classList.contains('collapsed') ? '+' : '−';
|
|
|
+ };
|
|
|
+
|
|
|
+ // 创建标签
|
|
|
+ const label = document.createElement('label');
|
|
|
+ label.textContent = '切换到Monad:';
|
|
|
+ label.htmlFor = 'web3-network-select';
|
|
|
+
|
|
|
+ // 创建下拉选择框
|
|
|
+ const select = document.createElement('select');
|
|
|
+ select.id = 'web3-network-select';
|
|
|
+
|
|
|
+ // 添加网络选项
|
|
|
+ networks.forEach(network => {
|
|
|
+ const option = document.createElement('option');
|
|
|
+ option.value = network.chainId;
|
|
|
+ option.textContent = network.name;
|
|
|
+ select.appendChild(option);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 添加状态显示
|
|
|
+ const status = document.createElement('div');
|
|
|
+ status.className = 'status';
|
|
|
+ status.textContent = '就绪';
|
|
|
+ status.id = 'web3-network-status';
|
|
|
+
|
|
|
+ // 添加事件监听器
|
|
|
+ select.addEventListener('change', function() {
|
|
|
+ const selectedChainId = this.value;
|
|
|
+ const selectedNetwork = networks.find(net => net.chainId === selectedChainId);
|
|
|
+
|
|
|
+ if (selectedNetwork) {
|
|
|
+ status.textContent = `切换中: ${selectedNetwork.name}...`;
|
|
|
+ status.style.color = '#4a90e2';
|
|
|
+ switchNetwork(selectedNetwork);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 添加到容器
|
|
|
+ container.appendChild(toggleBtn);
|
|
|
+ container.appendChild(label);
|
|
|
+ container.appendChild(select);
|
|
|
+ container.appendChild(status);
|
|
|
+
|
|
|
+ // 添加到页面
|
|
|
+ document.body.appendChild(container);
|
|
|
+
|
|
|
+ // 添加拖动功能
|
|
|
+ makeDraggable(container);
|
|
|
+ }
|
|
|
+
|
|
|
+ async function switchNetwork(network) {
|
|
|
+ const status = document.getElementById('web3-network-status');
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 尝试切换到指定网络
|
|
|
+ await window.ethereum.request({
|
|
|
+ method: 'wallet_switchEthereumChain',
|
|
|
+ params: [{ chainId: network.chainId }],
|
|
|
+ });
|
|
|
+
|
|
|
+ status.textContent = `已切换到 ${network.name}`;
|
|
|
+ status.style.color = 'green';
|
|
|
+
|
|
|
+ } catch (switchError) {
|
|
|
+ // 如果网络未添加,尝试添加它
|
|
|
+ if (switchError.code === 4902) {
|
|
|
+ status.textContent = '添加新网络中...';
|
|
|
+ status.style.color = '#4a90e2';
|
|
|
+
|
|
|
+ try {
|
|
|
+ await window.ethereum.request({
|
|
|
+ method: 'wallet_addEthereumChain',
|
|
|
+ params: [{
|
|
|
+ chainId: network.chainId,
|
|
|
+ chainName: network.name,
|
|
|
+ rpcUrls: network.rpcUrls,
|
|
|
+ nativeCurrency: {
|
|
|
+ name: 'MON',
|
|
|
+ symbol: 'MON',
|
|
|
+ decimals: 18
|
|
|
+ },
|
|
|
+ blockExplorerUrls: ['https://explorer.monad.xyz']
|
|
|
+ }],
|
|
|
+ });
|
|
|
+
|
|
|
+ status.textContent = `已添加并切换到 ${network.name}`;
|
|
|
+ status.style.color = 'green';
|
|
|
+
|
|
|
+ } catch (addError) {
|
|
|
+ status.textContent = `添加失败: ${addError.message}`;
|
|
|
+ status.style.color = 'red';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ status.textContent = `切换失败: ${switchError.message}`;
|
|
|
+ status.style.color = 'red';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeDraggable(element) {
|
|
|
+ let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
|
|
|
+
|
|
|
+ element.onmousedown = dragMouseDown;
|
|
|
+
|
|
|
+ function dragMouseDown(e) {
|
|
|
+ if (e.target.tagName === 'SELECT' || e.target.tagName === 'OPTION') return;
|
|
|
+
|
|
|
+ e = e || window.event;
|
|
|
+ e.preventDefault();
|
|
|
+ pos3 = e.clientX;
|
|
|
+ pos4 = e.clientY;
|
|
|
+ document.onmouseup = closeDragElement;
|
|
|
+ document.onmousemove = elementDrag;
|
|
|
+ }
|
|
|
+
|
|
|
+ function elementDrag(e) {
|
|
|
+ e = e || window.event;
|
|
|
+ e.preventDefault();
|
|
|
+ pos1 = pos3 - e.clientX;
|
|
|
+ pos2 = pos4 - e.clientY;
|
|
|
+ pos3 = e.clientX;
|
|
|
+ pos4 = e.clientY;
|
|
|
+ element.style.top = (element.offsetTop - pos2) + "px";
|
|
|
+ element.style.right = "unset";
|
|
|
+ element.style.left = (element.offsetLeft - pos1) + "px";
|
|
|
+ }
|
|
|
+
|
|
|
+ function closeDragElement() {
|
|
|
+ document.onmouseup = null;
|
|
|
+ document.onmousemove = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+})();
|