Add NIP 55 signer support
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
build
|
build
|
||||||
|
.vscode
|
||||||
Generated
+217
-280
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ import {ctx, memoize, omit, equals, assoc} from "@welshman/lib"
|
|||||||
import {createEvent} from "@welshman/util"
|
import {createEvent} from "@welshman/util"
|
||||||
import {withGetter, synced} from "@welshman/store"
|
import {withGetter, synced} from "@welshman/store"
|
||||||
import {type Nip46Handler} from "@welshman/signer"
|
import {type Nip46Handler} from "@welshman/signer"
|
||||||
import {Nip46Broker, Nip46Signer, Nip07Signer, Nip01Signer} from "@welshman/signer"
|
import {Nip46Broker, Nip46Signer, Nip07Signer, Nip01Signer, Nip55Signer} from "@welshman/signer"
|
||||||
|
|
||||||
export type Session = {
|
export type Session = {
|
||||||
method: string
|
method: string
|
||||||
@@ -11,6 +11,7 @@ export type Session = {
|
|||||||
token?: string
|
token?: string
|
||||||
secret?: string
|
secret?: string
|
||||||
handler?: Nip46Handler
|
handler?: Nip46Handler
|
||||||
|
signer?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pubkey = withGetter(synced<string | null>("pubkey", null))
|
export const pubkey = withGetter(synced<string | null>("pubkey", null))
|
||||||
@@ -50,6 +51,8 @@ export const getSigner = memoize((session: Session) => {
|
|||||||
return new Nip01Signer(session.secret!)
|
return new Nip01Signer(session.secret!)
|
||||||
case "nip46":
|
case "nip46":
|
||||||
return new Nip46Signer(Nip46Broker.get(session.pubkey, session.secret!, session.handler!))
|
return new Nip46Signer(Nip46Broker.get(session.pubkey, session.secret!, session.handler!))
|
||||||
|
case "nip55":
|
||||||
|
return new Nip55Signer(session.signer!)
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,8 @@
|
|||||||
"@welshman/net": "0.0.22",
|
"@welshman/net": "0.0.22",
|
||||||
"@welshman/util": "0.0.33",
|
"@welshman/util": "0.0.33",
|
||||||
"nostr-tools": "^2.7.2"
|
"nostr-tools": "^2.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"nostr-signer-capacitor-plugin": "github:chebizarro/nostr-signer-capacitor-plugin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ export * from './nip59'
|
|||||||
export * from './signers/nip01'
|
export * from './signers/nip01'
|
||||||
export * from './signers/nip07'
|
export * from './signers/nip07'
|
||||||
export * from './signers/nip46'
|
export * from './signers/nip46'
|
||||||
|
export * from './signers/nip55'
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
import {SignedEvent, StampedEvent} from "@welshman/util"
|
||||||
|
import {hash, own, ISigner} from "../util"
|
||||||
|
import {NostrSignerPlugin, AppInfo} from "nostr-signer-capacitor-plugin"
|
||||||
|
import {nip19} from "nostr-tools"
|
||||||
|
|
||||||
|
export const getNip55 = async (): Promise<AppInfo[]> => {
|
||||||
|
const {apps} = await NostrSignerPlugin.getInstalledSignerApps()
|
||||||
|
return apps
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Nip55Signer implements ISigner {
|
||||||
|
#lock = Promise.resolve()
|
||||||
|
#plugin = NostrSignerPlugin
|
||||||
|
#packageName: string
|
||||||
|
#packageNameSet = false
|
||||||
|
#npub?: string
|
||||||
|
#publicKey?: string
|
||||||
|
|
||||||
|
constructor(packageName: string) {
|
||||||
|
this.#packageName = packageName
|
||||||
|
this.#initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
async #initialize() {
|
||||||
|
if (!this.#packageNameSet) {
|
||||||
|
await this.#plugin.setPackageName({packageName: this.#packageName})
|
||||||
|
this.#packageNameSet = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#then = async <T>(f: (signer: typeof NostrSignerPlugin) => T | Promise<T>): Promise<T> => {
|
||||||
|
const promise = this.#lock.then(async () => {
|
||||||
|
if (!this.#packageNameSet) {
|
||||||
|
try {
|
||||||
|
await this.#plugin.setPackageName({packageName: this.#packageName})
|
||||||
|
this.#packageNameSet = true
|
||||||
|
} catch (error) {
|
||||||
|
this.#packageNameSet = false
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return f(this.#plugin)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.#lock = promise.then(() => Promise.resolve())
|
||||||
|
|
||||||
|
return promise
|
||||||
|
}
|
||||||
|
|
||||||
|
getPubkey = async (): Promise<string> => {
|
||||||
|
return this.#then(async signer => {
|
||||||
|
if (!this.#publicKey || !this.#npub) {
|
||||||
|
try {
|
||||||
|
const {npub} = await signer.getPublicKey()
|
||||||
|
this.#npub = npub
|
||||||
|
const {data} = nip19.decode(npub)
|
||||||
|
this.#publicKey = data as string
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Failed to get public key`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.#publicKey
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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))}
|
||||||
|
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
nip04 = {
|
||||||
|
encrypt: async (recipientPubKey: string, message: string): Promise<string> => {
|
||||||
|
const myNpub = this.#npub
|
||||||
|
if (!myNpub) {
|
||||||
|
await this.getPubkey()
|
||||||
|
}
|
||||||
|
return this.#then(async signer => {
|
||||||
|
const {result} = await signer.nip04Encrypt({
|
||||||
|
pubKey: recipientPubKey,
|
||||||
|
plainText: message,
|
||||||
|
npub: this.#npub!,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
},
|
||||||
|
decrypt: async (senderPubKey: string, message: string): Promise<string> => {
|
||||||
|
const myNpub = this.#npub
|
||||||
|
if (!myNpub) {
|
||||||
|
await this.getPubkey()
|
||||||
|
}
|
||||||
|
return this.#then(async signer => {
|
||||||
|
const {result} = await signer.nip04Decrypt({
|
||||||
|
pubKey: senderPubKey,
|
||||||
|
encryptedText: message,
|
||||||
|
npub: this.#npub!,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
nip44 = {
|
||||||
|
encrypt: async (recipientPubKey: string, message: string): Promise<string> => {
|
||||||
|
const myNpub = this.#npub
|
||||||
|
if (!myNpub) {
|
||||||
|
await this.getPubkey()
|
||||||
|
}
|
||||||
|
return this.#then(async signer => {
|
||||||
|
const {result} = await signer.nip44Encrypt({
|
||||||
|
pubKey: recipientPubKey,
|
||||||
|
plainText: message,
|
||||||
|
npub: this.#npub!,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
},
|
||||||
|
decrypt: async (senderPubKey: string, message: string): Promise<string> => {
|
||||||
|
const myNpub = this.#npub
|
||||||
|
if (!myNpub) {
|
||||||
|
await this.getPubkey()
|
||||||
|
}
|
||||||
|
return this.#then(async signer => {
|
||||||
|
const {result} = await signer.nip44Decrypt({
|
||||||
|
pubKey: senderPubKey,
|
||||||
|
encryptedText: message,
|
||||||
|
npub: this.#npub!,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user