mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-11-18 01:56:30 +01:00
docstrings for many functions.
This commit is contained in:
@@ -9,15 +9,20 @@ import (
|
||||
"github.com/nbd-wtf/go-nostr/nip46"
|
||||
)
|
||||
|
||||
// BunkerSigner is a signer that asks a bunker using NIP-46 every time it needs to do an operation.
|
||||
// BunkerSigner is a signer that delegates operations to a remote bunker using NIP-46.
|
||||
// It communicates with the bunker for all cryptographic operations rather than
|
||||
// handling the private key locally.
|
||||
type BunkerSigner struct {
|
||||
bunker *nip46.BunkerClient
|
||||
}
|
||||
|
||||
// NewBunkerSignerFromBunkerClient creates a new BunkerSigner from an existing BunkerClient.
|
||||
func NewBunkerSignerFromBunkerClient(bc *nip46.BunkerClient) BunkerSigner {
|
||||
return BunkerSigner{bc}
|
||||
}
|
||||
|
||||
// GetPublicKey retrieves the public key from the remote bunker.
|
||||
// It uses a timeout to prevent hanging indefinitely.
|
||||
func (bs BunkerSigner) GetPublicKey(ctx context.Context) (string, error) {
|
||||
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*30, errors.New("get_public_key took too long"))
|
||||
defer cancel()
|
||||
@@ -28,16 +33,20 @@ func (bs BunkerSigner) GetPublicKey(ctx context.Context) (string, error) {
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
// SignEvent sends the event to the remote bunker for signing.
|
||||
// It uses a timeout to prevent hanging indefinitely.
|
||||
func (bs BunkerSigner) SignEvent(ctx context.Context, evt *nostr.Event) error {
|
||||
ctx, cancel := context.WithTimeoutCause(ctx, time.Second*30, errors.New("sign_event took too long"))
|
||||
defer cancel()
|
||||
return bs.bunker.SignEvent(ctx, evt)
|
||||
}
|
||||
|
||||
// Encrypt encrypts a plaintext message for a recipient using the remote bunker.
|
||||
func (bs BunkerSigner) Encrypt(ctx context.Context, plaintext string, recipient string) (string, error) {
|
||||
return bs.bunker.NIP44Encrypt(ctx, recipient, plaintext)
|
||||
}
|
||||
|
||||
// Decrypt decrypts a base64-encoded ciphertext from a sender using the remote bunker.
|
||||
func (bs BunkerSigner) Decrypt(ctx context.Context, base64ciphertext string, sender string) (plaintext string, err error) {
|
||||
return bs.bunker.NIP44Encrypt(ctx, sender, base64ciphertext)
|
||||
}
|
||||
|
||||
@@ -9,13 +9,18 @@ import (
|
||||
"github.com/nbd-wtf/go-nostr/nip49"
|
||||
)
|
||||
|
||||
// EncryptedKeySigner is a signer that must always ask the user for a password before every operation.
|
||||
// EncryptedKeySigner is a signer that must ask the user for a password before every operation.
|
||||
// It stores the private key in encrypted form (NIP-49) and uses a callback to request the password
|
||||
// when needed for operations.
|
||||
type EncryptedKeySigner struct {
|
||||
ncryptsec string
|
||||
pk string
|
||||
callback func(context.Context) string
|
||||
}
|
||||
|
||||
// GetPublicKey returns the public key associated with this signer.
|
||||
// If the public key is not cached, it will decrypt the private key using the password
|
||||
// callback to derive the public key.
|
||||
func (es *EncryptedKeySigner) GetPublicKey(ctx context.Context) (string, error) {
|
||||
if es.pk != "" {
|
||||
return es.pk, nil
|
||||
@@ -33,6 +38,8 @@ func (es *EncryptedKeySigner) GetPublicKey(ctx context.Context) (string, error)
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
// SignEvent signs the provided event by first decrypting the private key
|
||||
// using the password callback, then signing the event with the decrypted key.
|
||||
func (es *EncryptedKeySigner) SignEvent(ctx context.Context, evt *nostr.Event) error {
|
||||
password := es.callback(ctx)
|
||||
sk, err := nip49.Decrypt(es.ncryptsec, password)
|
||||
@@ -43,6 +50,8 @@ func (es *EncryptedKeySigner) SignEvent(ctx context.Context, evt *nostr.Event) e
|
||||
return evt.Sign(sk)
|
||||
}
|
||||
|
||||
// Encrypt encrypts a plaintext message for a recipient using NIP-44.
|
||||
// It first decrypts the private key using the password callback.
|
||||
func (es EncryptedKeySigner) Encrypt(ctx context.Context, plaintext string, recipient string) (c64 string, err error) {
|
||||
password := es.callback(ctx)
|
||||
sk, err := nip49.Decrypt(es.ncryptsec, password)
|
||||
@@ -56,6 +65,8 @@ func (es EncryptedKeySigner) Encrypt(ctx context.Context, plaintext string, reci
|
||||
return nip44.Encrypt(plaintext, ck)
|
||||
}
|
||||
|
||||
// Decrypt decrypts a base64-encoded ciphertext from a sender using NIP-44.
|
||||
// It first decrypts the private key using the password callback.
|
||||
func (es EncryptedKeySigner) Decrypt(ctx context.Context, base64ciphertext string, sender string) (plaintext string, err error) {
|
||||
password := es.callback(ctx)
|
||||
sk, err := nip49.Decrypt(es.ncryptsec, password)
|
||||
|
||||
26
keyer/lib.go
26
keyer/lib.go
@@ -22,19 +22,37 @@ var (
|
||||
_ nostr.Keyer = (*ManualSigner)(nil)
|
||||
)
|
||||
|
||||
// SignerOptions contains configuration options for creating a new signer.
|
||||
type SignerOptions struct {
|
||||
// BunkerClientSecretKey is the secret key used for the bunker client
|
||||
BunkerClientSecretKey string
|
||||
BunkerSignTimeout time.Duration
|
||||
BunkerAuthHandler func(string)
|
||||
|
||||
// if a PasswordHandler is provided the key will be stored encrypted and this function will be called
|
||||
// BunkerSignTimeout is the timeout duration for bunker signing operations
|
||||
BunkerSignTimeout time.Duration
|
||||
|
||||
// BunkerAuthHandler is called when authentication is needed for bunker operations
|
||||
BunkerAuthHandler func(string)
|
||||
|
||||
// PasswordHandler is called when an operation needs access to the encrypted key.
|
||||
// If provided, the key will be stored encrypted and this function will be called
|
||||
// every time an operation needs access to the key so the user can be prompted.
|
||||
PasswordHandler func(context.Context) string
|
||||
|
||||
// if instead a Password is provided along with a ncryptsec, then the key will be decrypted and stored in plaintext.
|
||||
// Password is used along with ncryptsec to decrypt the key.
|
||||
// If provided, the key will be decrypted and stored in plaintext.
|
||||
Password string
|
||||
}
|
||||
|
||||
// New creates a new Keyer implementation based on the input string format.
|
||||
// It supports various input formats:
|
||||
// - ncryptsec: Creates an EncryptedKeySigner or KeySigner depending on options
|
||||
// - NIP-46 bunker URL or NIP-05 identifier: Creates a BunkerSigner
|
||||
// - nsec: Creates a KeySigner
|
||||
// - hex private key: Creates a KeySigner
|
||||
//
|
||||
// The context is used for operations that may require network access.
|
||||
// The pool is used for relay connections when needed.
|
||||
// Options are used for additional pieces required for EncryptedKeySigner and BunkerSigner.
|
||||
func New(ctx context.Context, pool *nostr.SimplePool, input string, opts *SignerOptions) (nostr.Keyer, error) {
|
||||
if opts == nil {
|
||||
opts = &SignerOptions{}
|
||||
|
||||
@@ -6,28 +6,40 @@ import (
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
)
|
||||
|
||||
// ManualSigner is a signer that doesn't really do anything, it just calls the functions given to it.
|
||||
// It can be used when an app for some reason wants to ask the user to manually provide a signed event
|
||||
// by copy-and-paste, for example.
|
||||
// ManualSigner is a signer that delegates all operations to user-provided functions.
|
||||
// It can be used when an app wants to ask the user or some custom server to manually provide a
|
||||
// signed event or an encrypted or decrypted payload by copy-and-paste, for example, or when the
|
||||
// app wants to implement custom signing logic.
|
||||
type ManualSigner struct {
|
||||
// ManualGetPublicKey is called when the public key is needed
|
||||
ManualGetPublicKey func(context.Context) (string, error)
|
||||
ManualSignEvent func(context.Context, *nostr.Event) error
|
||||
ManualEncrypt func(ctx context.Context, plaintext string, recipientPublicKey string) (base64ciphertext string, err error)
|
||||
ManualDecrypt func(ctx context.Context, base64ciphertext string, senderPublicKey string) (plaintext string, err error)
|
||||
|
||||
// ManualSignEvent is called when an event needs to be signed
|
||||
ManualSignEvent func(context.Context, *nostr.Event) error
|
||||
|
||||
// ManualEncrypt is called when a message needs to be encrypted
|
||||
ManualEncrypt func(ctx context.Context, plaintext string, recipientPublicKey string) (base64ciphertext string, err error)
|
||||
|
||||
// ManualDecrypt is called when a message needs to be decrypted
|
||||
ManualDecrypt func(ctx context.Context, base64ciphertext string, senderPublicKey string) (plaintext string, err error)
|
||||
}
|
||||
|
||||
// SignEvent delegates event signing to the ManualSignEvent function.
|
||||
func (ms ManualSigner) SignEvent(ctx context.Context, evt *nostr.Event) error {
|
||||
return ms.ManualSignEvent(ctx, evt)
|
||||
}
|
||||
|
||||
// GetPublicKey delegates public key retrieval to the ManualGetPublicKey function.
|
||||
func (ms ManualSigner) GetPublicKey(ctx context.Context) (string, error) {
|
||||
return ms.ManualGetPublicKey(ctx)
|
||||
}
|
||||
|
||||
// Encrypt delegates encryption to the ManualEncrypt function.
|
||||
func (ms ManualSigner) Encrypt(ctx context.Context, plaintext string, recipient string) (c64 string, err error) {
|
||||
return ms.ManualEncrypt(ctx, plaintext, recipient)
|
||||
}
|
||||
|
||||
// Decrypt delegates decryption to the ManualDecrypt function.
|
||||
func (ms ManualSigner) Decrypt(ctx context.Context, base64ciphertext string, sender string) (plaintext string, err error) {
|
||||
return ms.ManualDecrypt(ctx, base64ciphertext, sender)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import (
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
)
|
||||
|
||||
// Keysigner is a signer that holds the private key in memory and can do all the operations instantly and easily.
|
||||
// KeySigner is a signer that holds the private key in memory and can perform
|
||||
// all operations instantly and easily.
|
||||
type KeySigner struct {
|
||||
sk string
|
||||
pk string
|
||||
@@ -16,6 +17,8 @@ type KeySigner struct {
|
||||
conversationKeys *xsync.MapOf[string, [32]byte]
|
||||
}
|
||||
|
||||
// NewPlainKeySigner creates a new KeySigner from a private key.
|
||||
// Returns an error if the private key is invalid.
|
||||
func NewPlainKeySigner(sec string) (KeySigner, error) {
|
||||
pk, err := nostr.GetPublicKey(sec)
|
||||
if err != nil {
|
||||
@@ -24,9 +27,15 @@ func NewPlainKeySigner(sec string) (KeySigner, error) {
|
||||
return KeySigner{sec, pk, xsync.NewMapOf[string, [32]byte]()}, nil
|
||||
}
|
||||
|
||||
// SignEvent signs the provided event with the signer's private key.
|
||||
// It sets the event's ID, PubKey, and Sig fields.
|
||||
func (ks KeySigner) SignEvent(ctx context.Context, evt *nostr.Event) error { return evt.Sign(ks.sk) }
|
||||
|
||||
// GetPublicKey returns the public key associated with this signer.
|
||||
func (ks KeySigner) GetPublicKey(ctx context.Context) (string, error) { return ks.pk, nil }
|
||||
|
||||
// Encrypt encrypts a plaintext message for a recipient using NIP-44.
|
||||
// It caches conversation keys for efficiency in repeated operations.
|
||||
func (ks KeySigner) Encrypt(ctx context.Context, plaintext string, recipient string) (string, error) {
|
||||
ck, ok := ks.conversationKeys.Load(recipient)
|
||||
if !ok {
|
||||
@@ -40,6 +49,8 @@ func (ks KeySigner) Encrypt(ctx context.Context, plaintext string, recipient str
|
||||
return nip44.Encrypt(plaintext, ck)
|
||||
}
|
||||
|
||||
// Decrypt decrypts a base64-encoded ciphertext from a sender using NIP-44.
|
||||
// It caches conversation keys for efficiency in repeated operations.
|
||||
func (ks KeySigner) Decrypt(ctx context.Context, base64ciphertext string, sender string) (string, error) {
|
||||
ck, ok := ks.conversationKeys.Load(sender)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user