diff --git a/.gitignore b/.gitignore index 3c3629e..a6bb1fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +*.build.js diff --git a/README.md b/README.md index 25ef631..931766d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It provides a `window.nostr` object which has the following methods: ``` async window.nostr.getPublicKey(): string // returns your public key as hex -async window.nostr.signEvent(event) // signs the given event in place +async window.nostr.signEvent(event): string // returns the signature as hex ``` --- diff --git a/build.js b/build.js new file mode 100755 index 0000000..8cd917d --- /dev/null +++ b/build.js @@ -0,0 +1,26 @@ +#!/usr/bin/env node + +const esbuild = require('esbuild') +const alias = require('esbuild-plugin-alias') + +esbuild.build({ + bundle: true, + entryPoints: ['./extension/options.js'], + outfile: './extension/options.build.js', + plugins: [ + alias({ + stream: require.resolve('readable-stream') + }) + ] +}) + +esbuild.build({ + bundle: true, + entryPoints: ['./extension/background.js'], + outfile: './extension/background.build.js', + plugins: [ + alias({ + stream: require.resolve('readable-stream') + }) + ] +}) diff --git a/extension/background.js b/extension/background.js index bd88a24..6e25461 100644 --- a/extension/background.js +++ b/extension/background.js @@ -1,9 +1,34 @@ -browser.runtime.onMessage.addListener((req, sender, reply) => { - switch (req.type) { - case 'getPublicKey': - reply({}) - break - case 'signEvent': - break +import browser from 'webextension-polyfill' +import {validateEvent, signEvent, getPublicKey} from 'nostr-tools' + +browser.runtime.onMessage.addListener(async (req, sender, reply) => { + let {type, params, host} = req + + try { + switch (type) { + case 'getPublicKey': { + let results = browser.storage.local.get('private_key') + if (results && results.private_key) { + reply(getPublicKey(results.private_key)) + } else { + reply({error: 'no private key found'}) + } + break + } + case 'signEvent': { + let {event} = params + if (!validateEvent(event)) return reply({error: 'invalid event'}) + + let results = browser.storage.local.get('private_key') + if (results && results.private_key) { + reply(signEvent(event, results.private_key)) + } else { + reply({error: 'no private key found'}) + } + break + } + } + } catch (error) { + reply({error}) } }) diff --git a/extension/content-script.js b/extension/content-script.js index 7a65ad2..aa9164d 100644 --- a/extension/content-script.js +++ b/extension/content-script.js @@ -6,19 +6,20 @@ document.head.appendChild(script) // listen for messages from that script window.addEventListener('message', async ev => { if (ev.source !== window) return - if (!ev.data || ev.data.ext !== 'nostr') { + if (!ev.data || ev.data.ext !== 'nos2x') { // pass on to background - var reply + var response try { - reply = browser.runtime.sendMessage({ - ...ev.data, + response = browser.runtime.sendMessage({ + type: ev.data.type, + params: ev.data.params, host: window.location.host }) } catch (error) { - reply = {error} + response = {error} } // return response - window.postMessage({id: ev.data.id, reply}) + window.postMessage({id: ev.data.id, ext: 'nos2x', response}) } }) diff --git a/extension/manifest.json b/extension/manifest.json index 82b6a70..8caeb2a 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -3,15 +3,10 @@ "description": "Nostr Signer Extension", "version": "0.0.1", "manifest_version": 2, - "icons": { - "16": "icons/icon-16x16.png", - "48": "icons/icon-48x48.png", - "128": "icons/icon-128x128.png" - }, "options_page": "options.html", "background": { "scripts": [ - "background.js" + "background.build.js" ], "persistent": false }, diff --git a/extension/nostr-provider.js b/extension/nostr-provider.js index b39c549..92e07f7 100644 --- a/extension/nostr-provider.js +++ b/extension/nostr-provider.js @@ -1,4 +1,45 @@ window.nostr = { - getPublicKey() {}, - signEvent(event) {} + _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}) + }, + + _call(type, params) { + return new Promise((resolve, reject) => { + let id = Math.random().toString().slice(4) + this._requests[id] = {resolve, reject} + window.postMessage( + { + id, + ext: 'nos2x', + type, + params + }, + '*' + ) + }) + } } + +window.addEventListener('message', message => { + if ( + !message.data || + message.data.ext !== 'nos2x' || + !window.nostr._requests[message.data.id] + ) + return + + if (message.data.response.error) { + window.nostr._requests[message.data.id].reject(message.data.response.error) + } else { + window.nostr._requests[message.data.id].resolve(message.data.response) + } +}) diff --git a/extension/options.html b/extension/options.html index e69de29..1b5a02c 100644 --- a/extension/options.html +++ b/extension/options.html @@ -0,0 +1,11 @@ + + + +