basic functionality, untested.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
*.build.js
|
||||||
|
|||||||
@@ -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.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
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
26
build.js
Executable file
26
build.js
Executable file
@@ -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')
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
@@ -1,9 +1,34 @@
|
|||||||
browser.runtime.onMessage.addListener((req, sender, reply) => {
|
import browser from 'webextension-polyfill'
|
||||||
switch (req.type) {
|
import {validateEvent, signEvent, getPublicKey} from 'nostr-tools'
|
||||||
case 'getPublicKey':
|
|
||||||
reply({})
|
browser.runtime.onMessage.addListener(async (req, sender, reply) => {
|
||||||
break
|
let {type, params, host} = req
|
||||||
case 'signEvent':
|
|
||||||
|
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
|
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})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,19 +6,20 @@ document.head.appendChild(script)
|
|||||||
// listen for messages from that script
|
// listen for messages from that script
|
||||||
window.addEventListener('message', async ev => {
|
window.addEventListener('message', async ev => {
|
||||||
if (ev.source !== window) return
|
if (ev.source !== window) return
|
||||||
if (!ev.data || ev.data.ext !== 'nostr') {
|
if (!ev.data || ev.data.ext !== 'nos2x') {
|
||||||
// pass on to background
|
// pass on to background
|
||||||
var reply
|
var response
|
||||||
try {
|
try {
|
||||||
reply = browser.runtime.sendMessage({
|
response = browser.runtime.sendMessage({
|
||||||
...ev.data,
|
type: ev.data.type,
|
||||||
|
params: ev.data.params,
|
||||||
host: window.location.host
|
host: window.location.host
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reply = {error}
|
response = {error}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return response
|
// return response
|
||||||
window.postMessage({id: ev.data.id, reply})
|
window.postMessage({id: ev.data.id, ext: 'nos2x', response})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,15 +3,10 @@
|
|||||||
"description": "Nostr Signer Extension",
|
"description": "Nostr Signer Extension",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"icons": {
|
|
||||||
"16": "icons/icon-16x16.png",
|
|
||||||
"48": "icons/icon-48x48.png",
|
|
||||||
"128": "icons/icon-128x128.png"
|
|
||||||
},
|
|
||||||
"options_page": "options.html",
|
"options_page": "options.html",
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"background.js"
|
"background.build.js"
|
||||||
],
|
],
|
||||||
"persistent": false
|
"persistent": false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,45 @@
|
|||||||
window.nostr = {
|
window.nostr = {
|
||||||
getPublicKey() {},
|
_requests: {},
|
||||||
signEvent(event) {}
|
_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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>nos2x</title>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Private Key:
|
||||||
|
<input id="privateKeyInput" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<script src="options.build.js"></script>
|
||||||
|
|||||||
15
extension/options.js
Normal file
15
extension/options.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* global document */
|
||||||
|
|
||||||
|
import browser from 'webextension-polyfill'
|
||||||
|
|
||||||
|
document.getElementById('privateKeyInput').addEventListener('input', ev => {
|
||||||
|
browser.storage.local
|
||||||
|
.set({private_key: document.getElementById('privateKeyInput').value})
|
||||||
|
.then(() => {
|
||||||
|
console.log('success')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
browser.storage.local.get('private_key').then(results => {
|
||||||
|
document.getElementById('privateKeyInput').value = results.private_key
|
||||||
|
})
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.14.11",
|
"esbuild": "^0.14.11",
|
||||||
|
"esbuild-plugin-alias": "^0.2.1",
|
||||||
"eslint": "^8.6.0",
|
"eslint": "^8.6.0",
|
||||||
|
"events": "^3.3.0",
|
||||||
"nostr-tools": "^0.17.0",
|
"nostr-tools": "^0.17.0",
|
||||||
"prettier": "^2.5.1"
|
"prettier": "^2.5.1",
|
||||||
|
"webextension-polyfill": "^0.8.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
yarn.lock
15
yarn.lock
@@ -367,6 +367,11 @@ esbuild-openbsd-64@0.14.11:
|
|||||||
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.11.tgz#caeff5f946f79a60ce7bcf88871ca4c71d3476e8"
|
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.11.tgz#caeff5f946f79a60ce7bcf88871ca4c71d3476e8"
|
||||||
integrity sha512-l18TZDjmvwW6cDeR4fmizNoxndyDHamGOOAenwI4SOJbzlJmwfr0jUgjbaXCUuYVOA964siw+Ix+A+bhALWg8Q==
|
integrity sha512-l18TZDjmvwW6cDeR4fmizNoxndyDHamGOOAenwI4SOJbzlJmwfr0jUgjbaXCUuYVOA964siw+Ix+A+bhALWg8Q==
|
||||||
|
|
||||||
|
esbuild-plugin-alias@^0.2.1:
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz#45a86cb941e20e7c2bc68a2bea53562172494fcb"
|
||||||
|
integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==
|
||||||
|
|
||||||
esbuild-sunos-64@0.14.11:
|
esbuild-sunos-64@0.14.11:
|
||||||
version "0.14.11"
|
version "0.14.11"
|
||||||
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.11.tgz#90ce7e1749c2958a53509b4bae7b8f7d98f276d6"
|
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.11.tgz#90ce7e1749c2958a53509b4bae7b8f7d98f276d6"
|
||||||
@@ -518,6 +523,11 @@ esutils@^2.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||||
|
|
||||||
|
events@^3.3.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||||
|
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||||
|
|
||||||
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
|
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
|
||||||
@@ -1007,6 +1017,11 @@ v8-compile-cache@^2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||||
|
|
||||||
|
webextension-polyfill@^0.8.0:
|
||||||
|
version "0.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.8.0.tgz#f80e9f4b7f81820c420abd6ffbebfa838c60e041"
|
||||||
|
integrity sha512-a19+DzlT6Kp9/UI+mF9XQopeZ+n2ussjhxHJ4/pmIGge9ijCDz7Gn93mNnjpZAk95T4Tae8iHZ6sSf869txqiQ==
|
||||||
|
|
||||||
websocket-polyfill@^0.0.3:
|
websocket-polyfill@^0.0.3:
|
||||||
version "0.0.3"
|
version "0.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/websocket-polyfill/-/websocket-polyfill-0.0.3.tgz#7321ada0f5f17516290ba1cb587ac111b74ce6a5"
|
resolved "https://registry.yarnpkg.com/websocket-polyfill/-/websocket-polyfill-0.0.3.tgz#7321ada0f5f17516290ba1cb587ac111b74ce6a5"
|
||||||
|
|||||||
Reference in New Issue
Block a user