Add HandleDelete and GetSerialsFromFilter methods, integrate admin keys handling, and enhance constraints API. Include a new CLI convert tool for key translation.
This commit is contained in:
@@ -31,7 +31,7 @@ func (d *D) CheckForDeleted(ev *event.E, admins [][]byte) (err error) {
|
||||
t := ev.Tags.GetFirst([]byte("d"))
|
||||
a := atag.T{
|
||||
Kind: kind.New(ev.Kind),
|
||||
PubKey: ev.Pubkey,
|
||||
Pubkey: ev.Pubkey,
|
||||
DTag: t.Value(),
|
||||
}
|
||||
at := a.Marshal(nil)
|
||||
@@ -135,7 +135,7 @@ func (d *D) CheckForDeleted(ev *event.E, admins [][]byte) (err error) {
|
||||
// construct a tag
|
||||
a := atag.T{
|
||||
Kind: kind.New(ev.Kind),
|
||||
PubKey: ev.Pubkey,
|
||||
Pubkey: ev.Pubkey,
|
||||
}
|
||||
at := a.Marshal(nil)
|
||||
if idxs, err = GetIndexesFromFilter(
|
||||
|
||||
@@ -2,6 +2,7 @@ package bech32encoding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"crypto.orly/ec"
|
||||
"crypto.orly/ec/bech32"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/log"
|
||||
"utils.orly"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -67,7 +69,9 @@ func PublicKeyToNpub(pk *secp256k1.PublicKey) (encoded []byte, err error) {
|
||||
|
||||
// NsecToSecretKey decodes a nostr secret key (nsec) and returns the secp256k1
|
||||
// secret key.
|
||||
func NsecToSecretKey(encoded []byte) (sk *secp256k1.SecretKey, err error) {
|
||||
func NsecToSecretKey[V constraints.Bytes](encoded V) (
|
||||
sk *secp256k1.SecretKey, err error,
|
||||
) {
|
||||
var b8 []byte
|
||||
if b8, err = NsecToBytes(encoded); chk.E(err) {
|
||||
return
|
||||
@@ -77,9 +81,9 @@ func NsecToSecretKey(encoded []byte) (sk *secp256k1.SecretKey, err error) {
|
||||
}
|
||||
|
||||
// NsecToBytes converts a nostr bech32 encoded secret key to raw bytes.
|
||||
func NsecToBytes(encoded []byte) (sk []byte, err error) {
|
||||
func NsecToBytes[V constraints.Bytes](encoded V) (sk []byte, err error) {
|
||||
var b5, hrp []byte
|
||||
if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
|
||||
if hrp, b5, err = bech32.Decode([]byte(encoded)); chk.E(err) {
|
||||
return
|
||||
}
|
||||
if !utils.FastEqual(hrp, SecHRP) {
|
||||
@@ -97,9 +101,9 @@ func NsecToBytes(encoded []byte) (sk []byte, err error) {
|
||||
}
|
||||
|
||||
// NpubToBytes converts a bech32 encoded public key to raw bytes.
|
||||
func NpubToBytes(encoded []byte) (pk []byte, err error) {
|
||||
func NpubToBytes[V constraints.Bytes](encoded V) (pk []byte, err error) {
|
||||
var b5, hrp []byte
|
||||
if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
|
||||
if hrp, b5, err = bech32.Decode([]byte(encoded)); chk.E(err) {
|
||||
return
|
||||
}
|
||||
if !utils.FastEqual(hrp, PubHRP) {
|
||||
@@ -118,9 +122,11 @@ func NpubToBytes(encoded []byte) (pk []byte, err error) {
|
||||
|
||||
// NpubToPublicKey decodes an nostr public key (npub) and returns an secp256k1
|
||||
// public key.
|
||||
func NpubToPublicKey(encoded []byte) (pk *secp256k1.PublicKey, err error) {
|
||||
func NpubToPublicKey[V constraints.Bytes](encoded V) (
|
||||
pk *secp256k1.PublicKey, err error,
|
||||
) {
|
||||
var b5, b8, hrp []byte
|
||||
if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
|
||||
if hrp, b5, err = bech32.Decode([]byte(encoded)); chk.E(err) {
|
||||
err = log.E.Err("ERROR: '%s'", err)
|
||||
return
|
||||
}
|
||||
@@ -134,14 +140,13 @@ func NpubToPublicKey(encoded []byte) (pk *secp256k1.PublicKey, err error) {
|
||||
if b8, err = ConvertFromBech32(b5); chk.E(err) {
|
||||
return
|
||||
}
|
||||
|
||||
return schnorr.ParsePubKey(b8[:schnorr.PubKeyBytesLen])
|
||||
}
|
||||
|
||||
// HexToPublicKey decodes a string that should be a 64 character long hex
|
||||
// encoded public key into a btcec.PublicKey that can be used to verify a
|
||||
// signature or encode to Bech32.
|
||||
func HexToPublicKey(pk string) (p *btcec.PublicKey, err error) {
|
||||
func HexToPublicKey[V constraints.Bytes](pk V) (p *btcec.PublicKey, err error) {
|
||||
if len(pk) != HexKeyLen {
|
||||
err = log.E.Err(
|
||||
"secret key is %d bytes, must be %d", len(pk),
|
||||
@@ -150,7 +155,7 @@ func HexToPublicKey(pk string) (p *btcec.PublicKey, err error) {
|
||||
return
|
||||
}
|
||||
var pb []byte
|
||||
if pb, err = hex.Dec(pk); chk.D(err) {
|
||||
if pb, err = hex.Dec(string(pk)); chk.D(err) {
|
||||
return
|
||||
}
|
||||
if p, err = schnorr.ParsePubKey(pb); chk.D(err) {
|
||||
@@ -159,17 +164,30 @@ func HexToPublicKey(pk string) (p *btcec.PublicKey, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func NpubOrHexToPublicKey(encoded []byte) (pk *btcec.PublicKey, err error) {
|
||||
if !bytes.HasPrefix([]byte("npub"), encoded) && len(encoded) == HexKeyLen {
|
||||
return HexToPublicKey(string(encoded))
|
||||
func NpubOrHexToPublicKey[V constraints.Bytes](encoded V) (
|
||||
pk *btcec.PublicKey, err error,
|
||||
) {
|
||||
if !strings.HasPrefix(
|
||||
"npub", string(encoded),
|
||||
) && len(encoded) == HexKeyLen {
|
||||
return HexToPublicKey(encoded)
|
||||
}
|
||||
return NpubToPublicKey(encoded)
|
||||
}
|
||||
|
||||
func NpubOrHexToPublicKeyBinary[V constraints.Bytes](enc V) (
|
||||
pkb []byte, err error,
|
||||
) {
|
||||
if bytes.HasPrefix([]byte(enc), []byte("npub")) {
|
||||
return NpubToBytes(enc)
|
||||
}
|
||||
return hex.Dec(string(enc))
|
||||
}
|
||||
|
||||
// HexToSecretKey decodes a string that should be a 64 character long hex
|
||||
// encoded public key into a btcec.PublicKey that can be used to verify a
|
||||
// signature or encode to Bech32.
|
||||
func HexToSecretKey(sk []byte) (s *btcec.SecretKey, err error) {
|
||||
func HexToSecretKey[V constraints.Bytes](sk V) (s *btcec.SecretKey, err error) {
|
||||
if len(sk) != HexKeyLen {
|
||||
err = log.E.Err(
|
||||
"secret key is %d bytes, must be %d", len(sk),
|
||||
@@ -178,7 +196,7 @@ func HexToSecretKey(sk []byte) (s *btcec.SecretKey, err error) {
|
||||
return
|
||||
}
|
||||
pb := make([]byte, schnorr.PubKeyBytesLen)
|
||||
if _, err = hex.DecBytes(pb, sk); chk.D(err) {
|
||||
if _, err = hex.DecBytes(pb, []byte(sk)); chk.D(err) {
|
||||
return
|
||||
}
|
||||
if s = secp256k1.SecKeyFromBytes(pb); chk.D(err) {
|
||||
@@ -189,9 +207,9 @@ func HexToSecretKey(sk []byte) (s *btcec.SecretKey, err error) {
|
||||
|
||||
// HexToNpub converts a raw 64 character hex encoded public key (as used in
|
||||
// standard nostr json events) to a bech32 encoded npub.
|
||||
func HexToNpub(publicKeyHex []byte) (s []byte, err error) {
|
||||
func HexToNpub[V constraints.Bytes](publicKeyHex V) (s []byte, err error) {
|
||||
b := make([]byte, schnorr.PubKeyBytesLen)
|
||||
if _, err = hex.DecBytes(b, publicKeyHex); chk.D(err) {
|
||||
if _, err = hex.DecBytes(b, []byte(publicKeyHex)); chk.D(err) {
|
||||
err = log.E.Err("failed to decode public key hex: %w", err)
|
||||
return
|
||||
}
|
||||
@@ -212,7 +230,7 @@ func BinToNpub(b []byte) (s []byte, err error) {
|
||||
}
|
||||
|
||||
// HexToNsec converts a hex encoded secret key to a bech32 encoded nsec.
|
||||
func HexToNsec(sk []byte) (nsec []byte, err error) {
|
||||
func HexToNsec[V constraints.Bytes](sk V) (nsec []byte, err error) {
|
||||
var s *btcec.SecretKey
|
||||
if s, err = HexToSecretKey(sk); chk.E(err) {
|
||||
return
|
||||
@@ -235,13 +253,12 @@ func BinToNsec(sk []byte) (nsec []byte, err error) {
|
||||
|
||||
// SecretKeyToHex converts a secret key to the hex encoding.
|
||||
func SecretKeyToHex(sk *btcec.SecretKey) (hexSec []byte) {
|
||||
hex.EncBytes(hexSec, sk.Serialize())
|
||||
return
|
||||
return hex.EncAppend(nil, sk.Serialize())
|
||||
}
|
||||
|
||||
// NsecToHex converts a bech32 encoded nostr secret key to a raw hexadecimal
|
||||
// string.
|
||||
func NsecToHex(nsec []byte) (hexSec []byte, err error) {
|
||||
func NsecToHex[V constraints.Bytes](nsec V) (hexSec []byte, err error) {
|
||||
var sk *secp256k1.SecretKey
|
||||
if sk, err = NsecToSecretKey(nsec); chk.E(err) {
|
||||
return
|
||||
|
||||
@@ -265,7 +265,7 @@ func TestEncodeDecodeNEventTestEncodeDecodeNEvent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func MustDecode[V string | []byte](s V) (b []byte) {
|
||||
func MustDecode[V constraints.Bytes](s V) (b []byte) {
|
||||
var err error
|
||||
if _, err = hex.Dec(string(s)); chk.E(err) {
|
||||
panic(err)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"lol.mleku.dev/errorf"
|
||||
"lol.mleku.dev/log"
|
||||
"utils.orly/units"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -30,7 +31,7 @@ var _ codec.Envelope = (*Challenge)(nil)
|
||||
func NewChallenge() *Challenge { return &Challenge{} }
|
||||
|
||||
// NewChallengeWith creates a new authenvelope.Challenge with provided bytes.
|
||||
func NewChallengeWith[V string | []byte](challenge V) *Challenge {
|
||||
func NewChallengeWith[V constraints.Bytes](challenge V) *Challenge {
|
||||
return &Challenge{[]byte(challenge)}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"interfaces.orly/codec"
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/errorf"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -118,7 +119,7 @@ func NewResponse() *Response { return new(Response) }
|
||||
// NewResponseFrom creates a new countenvelope.Response with provided string for the
|
||||
// subscription.Id, a count and optional variadic approximate flag, which is
|
||||
// otherwise false and does not get rendered into the JSON.
|
||||
func NewResponseFrom[V string | []byte](
|
||||
func NewResponseFrom[V constraints.Bytes](
|
||||
s V, cnt int,
|
||||
approx ...bool,
|
||||
) (res *Response, err error) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"lol.mleku.dev/errorf"
|
||||
"utils.orly/bufpool"
|
||||
"utils.orly/units"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -103,7 +104,7 @@ func NewResult() *Result { return &Result{} }
|
||||
|
||||
// NewResultWith creates a new eventenvelope.Result with a provided
|
||||
// subscription.Id string and event.E.
|
||||
func NewResultWith[V string | []byte](s V, ev *event.E) (
|
||||
func NewResultWith[V constraints.Bytes](s V, ev *event.E) (
|
||||
res *Result, err error,
|
||||
) {
|
||||
if len(s) < 0 || len(s) > 64 {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"encoders.orly/text"
|
||||
"interfaces.orly/codec"
|
||||
"lol.mleku.dev/chk"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -28,7 +29,7 @@ var _ codec.Envelope = (*T)(nil)
|
||||
func New() *T { return &T{} }
|
||||
|
||||
// NewFrom creates a new noticeenvelope.T with a provided message.
|
||||
func NewFrom[V string | []byte](msg V) *T { return &T{Message: []byte(msg)} }
|
||||
func NewFrom[V constraints.Bytes](msg V) *T { return &T{Message: []byte(msg)} }
|
||||
|
||||
// Label returns the label of a NOTICE envelope.
|
||||
func (en *T) Label() string { return L }
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/errorf"
|
||||
"lol.mleku.dev/log"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -34,7 +35,7 @@ func New() *T { return &T{} }
|
||||
|
||||
// NewFrom creates a new okenvelope.T with a string for the subscription.Id and
|
||||
// the optional reason.
|
||||
func NewFrom[V string | []byte](eid V, ok bool, msg ...V) *T {
|
||||
func NewFrom[V constraints.Bytes](eid V, ok bool, msg ...V) *T {
|
||||
var m []byte
|
||||
if len(msg) > 0 {
|
||||
m = []byte(msg[0])
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"encoders.orly/text"
|
||||
"interfaces.orly/codec"
|
||||
"lol.mleku.dev/chk"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
// L is the label associated with this type of codec.Envelope.
|
||||
@@ -39,7 +40,7 @@ func NewFrom(id []byte, ff *filter.S) *T {
|
||||
}
|
||||
}
|
||||
|
||||
func NewWithId[V string | []byte](id V, ff *filter.S) (sub *T) {
|
||||
func NewWithId[V constraints.Bytes](id V, ff *filter.S) (sub *T) {
|
||||
return &T{
|
||||
Subscription: []byte(id),
|
||||
Filters: ff,
|
||||
|
||||
5
pkg/utils/constraints/constraints.go
Normal file
5
pkg/utils/constraints/constraints.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package constraints
|
||||
|
||||
type Bytes interface {
|
||||
~string | ~[]byte
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package utils
|
||||
|
||||
func FastEqual[A string | []byte, B string | []byte](a A, b B) (same bool) {
|
||||
import "utils.orly/constraints"
|
||||
|
||||
func FastEqual[A constraints.Bytes, B constraints.Bytes](a A, b B) (same bool) {
|
||||
if len(a) != len(b) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"encoders.orly/ints"
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/log"
|
||||
"utils.orly/constraints"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -29,7 +30,7 @@ var (
|
||||
// - Adds ws:// to addresses with any other port
|
||||
//
|
||||
// - Converts http/s to ws/s
|
||||
func URL[V string | []byte](v V) (b []byte) {
|
||||
func URL[V constraints.Bytes](v V) (b []byte) {
|
||||
u := []byte(v)
|
||||
if len(u) == 0 {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user