Serialize NIP07 extension calls

This commit is contained in:
styppo 2023-01-26 20:51:47 +00:00
parent 77b4d3a65f
commit 1ff056870c
No known key found for this signature in database
GPG Key ID: 3AAA685C50724C28
3 changed files with 49 additions and 12 deletions

View File

@ -1,6 +1,8 @@
import {defineStore} from 'pinia' import {defineStore} from 'pinia'
import {useSettingsStore} from 'stores/Settings' import {useSettingsStore} from 'stores/Settings'
import {useNostrStore} from 'src/nostr/NostrStore' import {useNostrStore} from 'src/nostr/NostrStore'
import {markRaw} from 'vue'
import JobQueue from 'src/utils/JobQueue'
export const useAppStore = defineStore('app', { export const useAppStore = defineStore('app', {
state: () => ({ state: () => ({
@ -13,6 +15,7 @@ export const useAppStore = defineStore('app', {
open: false, open: false,
params: {}, params: {},
}, },
queue: markRaw(new JobQueue()),
}), }),
getters: { getters: {
activeAccount() { activeAccount() {
@ -28,11 +31,13 @@ export const useAppStore = defineStore('app', {
}, },
actions: { actions: {
signIn(fragment = 'welcome') { signIn(fragment = 'welcome') {
return new Promise(resolve => { return this.queue.push(
this.signInDialog.callback = resolve () => new Promise(resolve => {
this.signInDialog.fragment = fragment this.signInDialog.callback = resolve
this.signInDialog.open = true this.signInDialog.fragment = fragment
}) this.signInDialog.open = true
})
)
}, },
signInIfNeeded(fragment = 'welcome') { signInIfNeeded(fragment = 'welcome') {
if (this.isSignedIn) return Promise.resolve(true) if (this.isSignedIn) return Promise.resolve(true)
@ -52,17 +57,17 @@ export const useAppStore = defineStore('app', {
async signEvent(event) { async signEvent(event) {
if (!await this.signInIfNeeded()) return if (!await this.signInIfNeeded()) return
if (!this.activeAccount.canSign() && !await this.signIn('private-key')) return if (!this.activeAccount.canSign() && !await this.signIn('private-key')) return
return this.activeAccount.sign(event) return await this.activeAccount.sign(event)
}, },
async decryptMessage(pubkey, content) { async decryptMessage(pubkey, content) {
if (!await this.signInIfNeeded()) return if (!await this.signInIfNeeded()) return
if (!this.activeAccount.canDecrypt() && !await this.signIn('private-key')) return if (!this.activeAccount.canDecrypt() && !await this.signIn('private-key')) return
return this.activeAccount.decrypt(pubkey, content) return await this.activeAccount.decrypt(pubkey, content)
}, },
async encryptMessage(pubkey, content) { async encryptMessage(pubkey, content) {
if (!await this.signInIfNeeded()) return if (!await this.signInIfNeeded()) return
if (!this.activeAccount.canEncrypt() && !await this.signIn('private-key')) return if (!this.activeAccount.canEncrypt() && !await this.signIn('private-key')) return
return this.activeAccount.encrypt(pubkey, content) return await this.activeAccount.encrypt(pubkey, content)
}, },
}, },
}) })

29
src/utils/JobQueue.js Normal file
View File

@ -0,0 +1,29 @@
export default class JobQueue {
constructor() {
this.queue = []
this.working = false
}
push(fn) {
return new Promise((resolve, reject) => {
this.queue.push({fn: fn, resolve: resolve, reject: reject})
if (!this.working) {
this.work().catch(e => console.error(e))
}
})
}
async work() {
this.working = true
while (this.queue.length > 0) {
const job = this.queue.shift()
try {
const result = await job.fn()
job.resolve(result)
} catch (e) {
if (job.reject) job.reject(e)
}
}
this.working = false
}
}

View File

@ -1,3 +1,5 @@
import JobQueue from 'src/utils/JobQueue'
export default class Nip07 { export default class Nip07 {
static isAvailable() { static isAvailable() {
return !!window.nostr return !!window.nostr
@ -9,21 +11,22 @@ export default class Nip07 {
static getPublicKey() { static getPublicKey() {
Nip07.enforceAvailable() Nip07.enforceAvailable()
return window.nostr.getPublicKey() return Nip07.queue.push(() => window.nostr.getPublicKey())
} }
static signEvent(event) { static signEvent(event) {
Nip07.enforceAvailable() Nip07.enforceAvailable()
return window.nostr.signEvent(event) return Nip07.queue.push(() => window.nostr.signEvent(event))
} }
static encrypt(pubkey, plaintext) { static encrypt(pubkey, plaintext) {
Nip07.enforceAvailable() Nip07.enforceAvailable()
return window.nostr.nip04.encrypt(pubkey, plaintext) return Nip07.queue.push(() => window.nostr.nip04.encrypt(pubkey, plaintext))
} }
static decrypt(pubkey, ciphertext) { static decrypt(pubkey, ciphertext) {
Nip07.enforceAvailable() Nip07.enforceAvailable()
return window.nostr.nip04.decrypt(pubkey, ciphertext) return Nip07.queue.push(() => window.nostr.nip04.decrypt(pubkey, ciphertext))
} }
} }
Nip07.queue = new JobQueue()