UNPKG

@arbius/aa-wallet

Version:

A secure and flexible Account Abstraction wallet implementation for Arbitrum One chain applications.

126 lines (125 loc) 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupEthereumProxy = setupEthereumProxy; const init_1 = require("./init"); const transactionQueue_1 = require("./transactionQueue"); // Store the original ethereum object let originalEthereum = null; /** * Setup the ethereum proxy to intercept window.ethereum calls */ function setupEthereumProxy() { // Ensure the wallet is initialized if (!(0, init_1.isInitialized)()) { throw new Error('AA Wallet must be initialized before setting up ethereum proxy'); } // Check if window.ethereum exists if (typeof window === 'undefined' || !window.ethereum) { console.warn('window.ethereum not found. Ethereum proxy not set up.'); return; } // Store the original ethereum object originalEthereum = window.ethereum; // Create the proxy const ethereumProxy = createEthereumProxy(originalEthereum); // Replace window.ethereum with our proxy Object.defineProperty(window, 'ethereum', { value: ethereumProxy, writable: true, configurable: true, }); console.log('Ethereum proxy set up successfully'); } /** * Create an ethereum proxy object * @param target The original ethereum object * @returns The proxied ethereum object */ function createEthereumProxy(target) { return new Proxy(target, { get(target, prop, receiver) { // Add the isAA flag if (prop === 'isAA') { return true; } // Get the original property const originalProp = Reflect.get(target, prop, receiver); // If the property is a function, we might need to intercept it if (typeof originalProp === 'function') { return function (...args) { // Intercept eth_sendTransaction requests if (prop === 'request' && args[0]?.method === 'eth_sendTransaction') { return handleSendTransaction(args[0]); } // Intercept personal_sign requests if (prop === 'request' && args[0]?.method === 'personal_sign') { return handlePersonalSign(args[0]); } // Pass through all other requests return originalProp.apply(this, args); }; } // Return the original property for everything else return originalProp; } }); } /** * Handle eth_sendTransaction requests * @param request The original request * @returns Promise resolving to the transaction hash */ async function handleSendTransaction(request) { console.log('Intercepted eth_sendTransaction:', request); // Get the current chain ID const chainId = await getCurrentChainId(); // Create a transaction object const transaction = { method: request.method, params: request.params, chainId, }; // Send the transaction through our transaction queue return (0, transactionQueue_1.sendTransaction)(transaction); } /** * Handle personal_sign requests * @param request The original request * @returns Promise resolving to the signature */ async function handlePersonalSign(request) { console.log('Intercepted personal_sign:', request); // Get the current website URL const websiteUrl = window.location.origin; const websiteName = new URL(websiteUrl).hostname; // Modify the message to include the website URL and address const [message, address] = request.params; const enhancedMessage = `Arbius Wallet: Create deterministic wallet on ${websiteName} for ${address}\nMake sure you check ${websiteName} is the same!`; // Create a new request with the enhanced message const enhancedRequest = { ...request, params: [enhancedMessage, address] }; // Pass through to the original ethereum object with enhanced message return originalEthereum.request(enhancedRequest); } /** * Get the current chain ID * @returns Promise resolving to the current chain ID */ async function getCurrentChainId() { // Try to get from the original ethereum object try { const chainIdHex = await originalEthereum.request({ method: 'eth_chainId' }); return parseInt(chainIdHex, 16); } catch (error) { // Fall back to the default chain ID from config const config = (0, init_1.getConfig)(); if (config) { return config.defaultChainId; } // Default to Ethereum mainnet if all else fails return 1; } }