Monorepo for Aesthetic.Computer aesthetic.computer
at main 114 lines 3.1 kB view raw
1// Keeps Wallet - Inpage Script 2// Creates window.keeps API for dApps to interact with 3 4(function() { 5 'use strict'; 6 7 // Request ID counter for matching responses 8 let requestId = 0; 9 const pendingRequests = new Map(); 10 11 // Listen for responses from content script 12 window.addEventListener('message', (event) => { 13 if (event.source !== window) return; 14 15 const { type, requestId: resId, payload } = event.data; 16 if (!type?.endsWith('_RESPONSE')) return; 17 18 const pending = pendingRequests.get(resId); 19 if (pending) { 20 pendingRequests.delete(resId); 21 if (payload?.error) { 22 pending.reject(new Error(payload.error)); 23 } else { 24 pending.resolve(payload); 25 } 26 } 27 }); 28 29 // Handle lock events 30 window.addEventListener('message', (event) => { 31 if (event.data?.type === 'KEEPS_LOCKED') { 32 window.dispatchEvent(new CustomEvent('keeps:locked')); 33 } 34 }); 35 36 // Send message to extension and wait for response 37 function sendMessage(type, payload = {}) { 38 return new Promise((resolve, reject) => { 39 const id = ++requestId; 40 pendingRequests.set(id, { resolve, reject }); 41 42 // Timeout after 30 seconds 43 setTimeout(() => { 44 if (pendingRequests.has(id)) { 45 pendingRequests.delete(id); 46 reject(new Error('Request timeout')); 47 } 48 }, 30000); 49 50 window.postMessage({ type, requestId: id, payload }, '*'); 51 }); 52 } 53 54 // Public API 55 window.keeps = { 56 // Check if extension is installed 57 async isInstalled() { 58 try { 59 const res = await sendMessage('KEEPS_PING'); 60 return res.success === true; 61 } catch { 62 return false; 63 } 64 }, 65 66 // Get wallet state 67 async getState() { 68 return sendMessage('KEEPS_GET_STATE'); 69 }, 70 71 // Get connected address (null if locked/no wallet) 72 async getAddress() { 73 const res = await sendMessage('KEEPS_GET_ADDRESS'); 74 return res.address; 75 }, 76 77 // Request connection (will prompt unlock if needed) 78 async connect() { 79 const state = await this.getState(); 80 if (!state.exists) { 81 throw new Error('No wallet found. Please create one in the extension.'); 82 } 83 if (!state.unlocked) { 84 throw new Error('Wallet is locked. Please unlock in the extension.'); 85 } 86 return state.address; 87 }, 88 89 // Get balance 90 async getBalance(network) { 91 return sendMessage('KEEPS_GET_BALANCE', { network }); 92 }, 93 94 // Get keeps (NFTs) 95 async getKeeps(network) { 96 return sendMessage('KEEPS_GET_KEEPS', { network }); 97 }, 98 99 // Request signing an operation 100 async sign(operation) { 101 return sendMessage('KEEPS_SIGN_OPERATION', { operation }); 102 }, 103 104 // Events 105 onLocked(callback) { 106 window.addEventListener('keeps:locked', callback); 107 return () => window.removeEventListener('keeps:locked', callback); 108 }, 109 }; 110 111 // Announce availability 112 window.dispatchEvent(new CustomEvent('keeps:ready')); 113 console.log('🔐 Keeps Wallet API available at window.keeps'); 114})();