const EXTENSION = 'nostrconnect' window.nostr = { _requests: {}, _pubkey: null, async getPublicKey() { if (this._pubkey) return this._pubkey this._pubkey = await this._call('getPublicKey', {}) return this._pubkey }, async signEvent(event) { return this._call('signEvent', { event }) }, async getRelays() { return this._call('getRelays', {}) }, nip04: { async encrypt(peer, plaintext) { return window.nostr._call('nip04.encrypt', { peer, plaintext }) }, async decrypt(peer, ciphertext) { return window.nostr._call('nip04.decrypt', { peer, ciphertext }) } }, _call(type, params) { const id = Math.random().toString().slice(-4) console.log( '%c[nostrconnect:%c' + id + '%c]%c calling %c' + type + '%c with %c' + JSON.stringify(params || {}), 'background-color:#f1b912;font-weight:bold;color:white', 'background-color:#f1b912;font-weight:bold;color:#a92727', 'background-color:#f1b912;color:white;font-weight:bold', 'color:auto', 'font-weight:bold;color:#08589d;font-family:monospace', 'color:auto', 'font-weight:bold;color:#90b12d;font-family:monospace' ) return new Promise((resolve, reject) => { this._requests[id] = { resolve, reject } window.postMessage( { id, ext: EXTENSION, type, params }, '*' ) }) } } window.addEventListener('message', (message) => { if ( !message.data || message.data.response === null || message.data.response === undefined || message.data.ext !== EXTENSION || !window.nostr._requests[message.data.id] ) return if (message.data.response.error) { const error = new Error( `${EXTENSION}: ${message.data.response.error.message}` ) error.stack = message.data.response.error.stack window.nostr._requests[message.data.id].reject(error) } else { window.nostr._requests[message.data.id].resolve(message.data.response) } console.log( '%c[nostrconnect:%c' + message.data.id + '%c]%c result: %c' + JSON.stringify( message?.data?.response || message?.data?.response?.error?.message || {} ), 'background-color:#f1b912;font-weight:bold;color:white', 'background-color:#f1b912;font-weight:bold;color:#a92727', 'background-color:#f1b912;color:white;font-weight:bold', 'color:auto', 'font-weight:bold;color:#08589d' ) delete window.nostr._requests[message.data.id] }) // hack to replace nostr:nprofile.../etc links with something else let replacing = null document.addEventListener('mousedown', replaceNostrSchemeLink) async function replaceNostrSchemeLink(e) { if (e.target.tagName !== 'A' || !e.target.href.startsWith('nostr:')) return if (replacing === false) return const response = await window.nostr._call('replaceURL', { url: e.target.href }) if (response === false) { replacing = false return } e.target.href = response }