Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Added signString() method
  • Loading branch information
robwoodgate committed Mar 21, 2025
commit 66c1c7da30119feb5d1d553553a77e0fd80261f5
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async window.nostr.nip04.encrypt(pubkey, plaintext): string // returns ciphertex
async window.nostr.nip04.decrypt(pubkey, ciphertext): string // takes ciphertext+iv as specified in nip04
async window.nostr.nip44.encrypt(pubkey, plaintext): string // takes pubkey, plaintext, returns ciphertext as specified in nip-44
async window.nostr.nip44.decrypt(pubkey, ciphertext): string // takes pubkey, ciphertext, returns plaintext as specified in nip-44
async window.nostr.signString(message): {hash: string, sig: string, pubkey: string} // return SHA256 `hash` of `message`, Schnorr `sig` of `hash`, `pubkey` of signer
```

This extension is Chromium-only. For a maintained Firefox fork, see [nos2x-fox](https://diegogurpegui.com/nos2x-fox/).
Expand Down
21 changes: 21 additions & 0 deletions extension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import * as nip04 from 'nostr-tools/nip04'
import * as nip44 from 'nostr-tools/nip44'
import {Mutex} from 'async-mutex'
import {LRUCache} from './utils'
import {sha256} from "@noble/hashes/sha256";
import {bytesToHex} from "@noble/hashes/utils";
import {schnorr} from "@noble/curves/secp256k1";

import {
NO_PERMISSIONS_REQUIRED,
Expand Down Expand Up @@ -200,6 +203,24 @@ async function performOperation(type, params) {
? event
: {error: {message: 'invalid event'}}
}
case 'signString': {
if (typeof params.message !== 'string') {
return { error: { message: "message is not a string" } };
}
try {
// Check this is not a stringified event
// trying to bypass permission checks
const obj = JSON.parse(params.message);
if (validateEvent(obj)){
return { error: { message: "use signEvent() to sign events" } };
}
} catch (e) {} // not a JSON string
const utf8Encoder = new TextEncoder();
const hash = bytesToHex(sha256(utf8Encoder.encode(params.message)));
const sig = bytesToHex(schnorr.sign(hash, sk));
const pubkey = bytesToHex(schnorr.getPublicKey(sk));
return {hash: hash, sig: sig, pubkey: pubkey};
}
case 'nip04.encrypt': {
let {peer, plaintext} = params
return nip04.encrypt(sk, peer, plaintext)
Expand Down
1 change: 1 addition & 0 deletions extension/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const NO_PERMISSIONS_REQUIRED = {
export const PERMISSION_NAMES = Object.fromEntries([
['getPublicKey', 'read your public key'],
['signEvent', 'sign events using your private key'],
['signString', 'sign messages using your private key'],
['nip04.encrypt', 'encrypt messages to peers'],
['nip04.decrypt', 'decrypt messages from peers'],
['nip44.encrypt', 'encrypt messages to peers'],
Expand Down
4 changes: 4 additions & 0 deletions extension/nostr-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ window.nostr = {
return this._call('signEvent', {event})
},

async signString(message) {
return this._call('signString', {message})
},

async getRelays() {
return {}
},
Expand Down