Add sign timeout to thunk
This commit is contained in:
@@ -20,8 +20,11 @@ import { makeEvent } from '@welshman/util'
|
||||
import { ISigner, Nip01Signer, makeSecret } from '@welshman/signer'
|
||||
|
||||
const signer: ISigner = new Nip01Signer(makeSecret())
|
||||
const options = {
|
||||
signal: AbortSignal.timeout(10_000),
|
||||
}
|
||||
|
||||
signer.sign(makeEvent(1)).then(signedEvent => console.log(signedEvent))
|
||||
signer.sign(makeEvent(1), options).then(signedEvent => console.log(signedEvent))
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -5,9 +5,15 @@ It includes methods for signing messages, verifying signatures, and encrypting/d
|
||||
|
||||
|
||||
```typescript
|
||||
export type SignOptions = {
|
||||
signal?: AbortSignal
|
||||
}
|
||||
|
||||
export type SignWithOptions = (event: StampedEvent, options?: SignOptions) => Promise<SignedEvent>
|
||||
|
||||
interface ISigner {
|
||||
// Core signing functionality
|
||||
sign: (event: StampedEvent) => Promise<SignedEvent>
|
||||
sign: SignWithOptions
|
||||
getPubkey: () => Promise<string>
|
||||
|
||||
// Encryption capabilities
|
||||
|
||||
@@ -8,7 +8,7 @@ class Nip01Signer implements ISigner {
|
||||
constructor(private secret: string)
|
||||
|
||||
// ISigner implementation
|
||||
sign: (event: StampedEvent) => Promise<SignedEvent>
|
||||
sign: SignWithOptions
|
||||
getPubkey: () => Promise<string>
|
||||
nip04: { encrypt, decrypt }
|
||||
nip44: { encrypt, decrypt }
|
||||
|
||||
@@ -55,7 +55,7 @@ class Nip55Signer implements ISigner {
|
||||
constructor(private secret: string)
|
||||
|
||||
// ISigner implementation
|
||||
sign: (event: StampedEvent) => Promise<SignedEvent>
|
||||
sign: SignWithOptions
|
||||
getPubkey: () => Promise<string>
|
||||
nip04: { encrypt, decrypt }
|
||||
nip44: { encrypt, decrypt }
|
||||
|
||||
@@ -132,9 +132,11 @@ export class Thunk {
|
||||
}
|
||||
|
||||
try {
|
||||
event = await signer.sign(event)
|
||||
event = await signer.sign(event, {
|
||||
signal: AbortSignal.timeout(15_000),
|
||||
})
|
||||
} catch (e: any) {
|
||||
return this._fail(`Failed to sign event: ${String(e.error || e)}`)
|
||||
return this._fail(String(e || "Failed to sign event"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
import {StampedEvent} from "@welshman/util"
|
||||
import {nip04, nip44, own, hash, sign, getPubkey, ISigner, makeSecret} from "../util.js"
|
||||
import {
|
||||
nip04,
|
||||
nip44,
|
||||
own,
|
||||
hash,
|
||||
sign,
|
||||
getPubkey,
|
||||
ISigner,
|
||||
SignOptions,
|
||||
signWithOptions,
|
||||
makeSecret,
|
||||
} from "../util.js"
|
||||
|
||||
export class Nip01Signer implements ISigner {
|
||||
#pubkey: string
|
||||
@@ -14,7 +25,8 @@ export class Nip01Signer implements ISigner {
|
||||
|
||||
getPubkey = async () => this.#pubkey
|
||||
|
||||
sign = async (event: StampedEvent) => sign(hash(own(event, this.#pubkey)), this.secret)
|
||||
sign = (event: StampedEvent, options: SignOptions = {}) =>
|
||||
signWithOptions(sign(hash(own(event, this.#pubkey)), this.secret), options)
|
||||
|
||||
nip04 = {
|
||||
encrypt: async (pubkey: string, message: string) => nip04.encrypt(pubkey, this.secret, message),
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import {StampedEvent} from "@welshman/util"
|
||||
import {hash, own, Sign, ISigner, EncryptionImplementation} from "../util.js"
|
||||
import {
|
||||
hash,
|
||||
own,
|
||||
signWithOptions,
|
||||
SignOptions,
|
||||
Sign,
|
||||
ISigner,
|
||||
EncryptionImplementation,
|
||||
} from "../util.js"
|
||||
|
||||
export type Nip07 = {
|
||||
signEvent: Sign
|
||||
@@ -33,11 +41,11 @@ export class Nip07Signer implements ISigner {
|
||||
|
||||
getPubkey = async () => this.#then<string>(ext => ext.getPublicKey() as string)
|
||||
|
||||
sign = async (template: StampedEvent) => {
|
||||
const event = hash(own(template, await this.getPubkey()))
|
||||
|
||||
return this.#then(ext => ext.signEvent(event))
|
||||
}
|
||||
sign = (template: StampedEvent, options: SignOptions = {}) =>
|
||||
signWithOptions(
|
||||
this.#then(async ext => ext.signEvent(hash(own(template, await ext.getPublicKey()!)))),
|
||||
options,
|
||||
)
|
||||
|
||||
nip04 = {
|
||||
encrypt: (pubkey: string, message: string) =>
|
||||
|
||||
@@ -7,7 +7,15 @@ import {
|
||||
NOSTR_CONNECT,
|
||||
} from "@welshman/util"
|
||||
import {publish, request, AdapterContext} from "@welshman/net"
|
||||
import {ISigner, EncryptionImplementation, decrypt, hash, own} from "../util.js"
|
||||
import {
|
||||
ISigner,
|
||||
EncryptionImplementation,
|
||||
signWithOptions,
|
||||
SignOptions,
|
||||
decrypt,
|
||||
hash,
|
||||
own,
|
||||
} from "../util.js"
|
||||
import {Nip01Signer} from "./nip01.js"
|
||||
|
||||
export type Nip46Context = {
|
||||
@@ -463,6 +471,9 @@ export class Nip46Signer implements ISigner {
|
||||
return this.pubkey
|
||||
}
|
||||
|
||||
sign = async (template: StampedEvent) =>
|
||||
this.broker.signEvent(hash(own(template, await this.getPubkey())))
|
||||
sign = (template: StampedEvent, options: SignOptions = {}) =>
|
||||
signWithOptions(
|
||||
this.getPubkey().then(pubkey => this.broker.signEvent(hash(own(template, pubkey)))),
|
||||
options,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {NostrSignerPlugin, AppInfo} from "nostr-signer-capacitor-plugin"
|
||||
import {decode} from "nostr-tools/nip19"
|
||||
import {SignedEvent, StampedEvent} from "@welshman/util"
|
||||
import {hash, own, ISigner} from "../util.js"
|
||||
import {hash, own, signWithOptions, SignOptions, ISigner} from "../util.js"
|
||||
|
||||
export const getNip55 = async (): Promise<AppInfo[]> => {
|
||||
const {apps} = await NostrSignerPlugin.getInstalledSignerApps()
|
||||
@@ -64,21 +64,23 @@ export class Nip55Signer implements ISigner {
|
||||
})
|
||||
}
|
||||
|
||||
sign = async (template: StampedEvent): Promise<SignedEvent> => {
|
||||
const pubkey = await this.getPubkey() // hex-encoded public key
|
||||
const npub = this.#npub! // Bech32-encoded public key
|
||||
const event = {sig: "", ...hash(own(template, pubkey))}
|
||||
sign = (template: StampedEvent, options: SignOptions = {}): Promise<SignedEvent> =>
|
||||
signWithOptions(
|
||||
this.getPubkey().then(pubkey => {
|
||||
const hashedEvent = hash(own(template, pubkey))
|
||||
|
||||
return this.#then(async signer => {
|
||||
const {event: signedEventJson} = await signer.signEvent({
|
||||
eventJson: JSON.stringify(event),
|
||||
eventId: event.id,
|
||||
npub: npub,
|
||||
})
|
||||
const signedEvent = JSON.parse(signedEventJson) as SignedEvent
|
||||
return signedEvent
|
||||
})
|
||||
}
|
||||
return this.#then(async signer => {
|
||||
const {event: json} = await signer.signEvent({
|
||||
eventJson: JSON.stringify({sig: "", ...hashedEvent}),
|
||||
eventId: hashedEvent.id,
|
||||
npub: this.#npub!,
|
||||
})
|
||||
|
||||
return JSON.parse(json) as SignedEvent
|
||||
})
|
||||
}),
|
||||
options,
|
||||
)
|
||||
|
||||
nip04 = {
|
||||
encrypt: async (recipientPubKey: string, message: string): Promise<string> => {
|
||||
|
||||
@@ -44,6 +44,12 @@ export const nip44 = {
|
||||
|
||||
export type Sign = (event: StampedEvent) => Promise<SignedEvent>
|
||||
|
||||
export type SignOptions = {
|
||||
signal?: AbortSignal
|
||||
}
|
||||
|
||||
export type SignWithOptions = (event: StampedEvent, options?: SignOptions) => Promise<SignedEvent>
|
||||
|
||||
export type Encrypt = (pubkey: string, message: string) => Promise<string>
|
||||
|
||||
export type Decrypt = (pubkey: string, message: string) => Promise<string>
|
||||
@@ -54,7 +60,7 @@ export type EncryptionImplementation = {
|
||||
}
|
||||
|
||||
export interface ISigner {
|
||||
sign: Sign
|
||||
sign: SignWithOptions
|
||||
nip04: EncryptionImplementation
|
||||
nip44: EncryptionImplementation
|
||||
getPubkey: () => Promise<string>
|
||||
@@ -75,8 +81,8 @@ export class WrappedSigner extends Emitter implements ISigner {
|
||||
super()
|
||||
}
|
||||
|
||||
sign(event: StampedEvent) {
|
||||
return this.wrapMethod("sign", () => this.signer.sign(event))
|
||||
sign(event: StampedEvent, options: SignOptions = {}) {
|
||||
return this.wrapMethod("sign", () => this.signer.sign(event, options))
|
||||
}
|
||||
|
||||
getPubkey() {
|
||||
@@ -97,3 +103,12 @@ export class WrappedSigner extends Emitter implements ISigner {
|
||||
this.wrapMethod("nip44.decrypt", () => this.signer.nip44.decrypt(pubkey, message)),
|
||||
}
|
||||
}
|
||||
|
||||
export const signWithOptions = (
|
||||
promise: Promise<SignedEvent> | SignedEvent,
|
||||
options: SignOptions,
|
||||
) =>
|
||||
new Promise<SignedEvent>((resolve, reject) => {
|
||||
Promise.resolve(promise).then(resolve)
|
||||
options.signal?.addEventListener("abort", () => reject("Signing was aborted"))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user