use xhex everywhere.
This commit is contained in:
10
envelopes.go
10
envelopes.go
@@ -1,7 +1,6 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
"github.com/templexxx/xhex"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
@@ -187,7 +187,7 @@ func (v *CountEnvelope) FromJSON(data string) error {
|
||||
if err := json.Unmarshal(unsafe.Slice(unsafe.StringData(arr[2].Raw), len(arr[2].Raw)), &countResult); err == nil && countResult.Count != nil {
|
||||
v.Count = countResult.Count
|
||||
if len(countResult.HLL) == 512 {
|
||||
v.HyperLogLog, err = hex.DecodeString(countResult.HLL)
|
||||
v.HyperLogLog, err = HexDecodeString(countResult.HLL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid \"hll\" value in COUNT message: %w", err)
|
||||
}
|
||||
@@ -214,7 +214,7 @@ func (v CountEnvelope) MarshalJSON() ([]byte, error) {
|
||||
if v.HyperLogLog != nil {
|
||||
w.RawString(`,"hll":"`)
|
||||
hllHex := make([]byte, 512)
|
||||
hex.Encode(hllHex, v.HyperLogLog)
|
||||
xhex.Encode(hllHex, v.HyperLogLog)
|
||||
w.Buffer.AppendBytes(hllHex)
|
||||
w.RawString(`"`)
|
||||
}
|
||||
@@ -365,7 +365,7 @@ func (v *OKEnvelope) FromJSON(data string) error {
|
||||
if len(arr) < 4 {
|
||||
return fmt.Errorf("failed to decode OK envelope: missing fields")
|
||||
}
|
||||
if _, err := hex.Decode(v.EventID[:], []byte(arr[1].Str)); err != nil {
|
||||
if err := xhex.Decode(v.EventID[:], []byte(arr[1].Str)); err != nil {
|
||||
return err
|
||||
}
|
||||
v.OK = arr[2].Raw == "true"
|
||||
@@ -377,7 +377,7 @@ func (v *OKEnvelope) FromJSON(data string) error {
|
||||
func (v OKEnvelope) MarshalJSON() ([]byte, error) {
|
||||
w := jwriter.Writer{NoEscapeHTML: true}
|
||||
w.RawString(`["OK","`)
|
||||
w.RawString(hex.EncodeToString(v.EventID[:]))
|
||||
w.RawString(HexEncodeToString(v.EventID[:]))
|
||||
w.RawString(`",`)
|
||||
ok := "false"
|
||||
if v.OK {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func TestParseMessage(t *testing.T) {
|
||||
@@ -139,6 +139,6 @@ func TestParseMessage(t *testing.T) {
|
||||
|
||||
func mustSigFromHex(sigStr string) [64]byte {
|
||||
var sig [64]byte
|
||||
hex.Decode(sig[:], unsafe.Slice(unsafe.StringData(sigStr), 128))
|
||||
xhex.Decode(sig[:], unsafe.Slice(unsafe.StringData(sigStr), 128))
|
||||
return sig
|
||||
}
|
||||
|
||||
11
event.go
11
event.go
@@ -2,10 +2,10 @@ package nostr
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
// Event represents a Nostr event.
|
||||
@@ -38,15 +38,12 @@ func (evt Event) CheckID() bool {
|
||||
func (evt Event) Serialize() []byte {
|
||||
// the serialization process is just putting everything into a JSON array
|
||||
// so the order is kept. See NIP-01
|
||||
dst := make([]byte, 0, 100+len(evt.Content)+len(evt.Tags)*80)
|
||||
return serializeEventInto(evt, dst)
|
||||
}
|
||||
dst := make([]byte, 4+64, 100+len(evt.Content)+len(evt.Tags)*80)
|
||||
|
||||
func serializeEventInto(evt Event, dst []byte) []byte {
|
||||
// the header portion is easy to serialize
|
||||
// [0,"pubkey",created_at,kind,[
|
||||
dst = append(dst, `[0,"`...)
|
||||
dst = hex.AppendEncode(dst, evt.PubKey[:])
|
||||
copy(dst, `[0,"`)
|
||||
xhex.Encode(dst[4:4+64], evt.PubKey[:]) // there will always be such capacity
|
||||
dst = append(dst, `",`...)
|
||||
dst = append(dst, strconv.FormatInt(int64(evt.CreatedAt), 10)...)
|
||||
dst = append(dst, `,`...)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func easyjsonDecodeEvent(in *jlexer.Lexer, out *Event) {
|
||||
@@ -29,12 +28,12 @@ func easyjsonDecodeEvent(in *jlexer.Lexer, out *Event) {
|
||||
case "id":
|
||||
b := in.UnsafeBytes()
|
||||
if len(b) == 64 {
|
||||
hex.Decode(out.ID[:], b)
|
||||
xhex.Decode(out.ID[:], b)
|
||||
}
|
||||
case "pubkey":
|
||||
b := in.UnsafeBytes()
|
||||
if len(b) == 64 {
|
||||
hex.Decode(out.PubKey[:], b)
|
||||
xhex.Decode(out.PubKey[:], b)
|
||||
}
|
||||
case "created_at":
|
||||
out.CreatedAt = Timestamp(in.Int64())
|
||||
@@ -73,7 +72,7 @@ func easyjsonDecodeEvent(in *jlexer.Lexer, out *Event) {
|
||||
case "sig":
|
||||
b := in.UnsafeBytes()
|
||||
if len(b) == 128 {
|
||||
hex.Decode(out.Sig[:], b)
|
||||
xhex.Decode(out.Sig[:], b)
|
||||
}
|
||||
}
|
||||
in.WantComma()
|
||||
@@ -92,12 +91,12 @@ func easyjsonEncodeEvent(out *jwriter.Writer, in Event) {
|
||||
|
||||
if in.ID != ZeroID {
|
||||
out.RawString(",\"id\":\"")
|
||||
out.RawString(hex.EncodeToString(in.ID[:]) + "\"")
|
||||
out.RawString(HexEncodeToString(in.ID[:]) + "\"")
|
||||
}
|
||||
|
||||
if in.PubKey != ZeroPK {
|
||||
out.RawString(",\"pubkey\":\"")
|
||||
out.RawString(hex.EncodeToString(in.PubKey[:]) + "\"")
|
||||
out.RawString(HexEncodeToString(in.PubKey[:]) + "\"")
|
||||
}
|
||||
|
||||
out.RawString(",\"created_at\":")
|
||||
@@ -125,7 +124,7 @@ func easyjsonEncodeEvent(out *jwriter.Writer, in Event) {
|
||||
|
||||
if in.Sig != [64]byte{} {
|
||||
out.RawString(",\"sig\":\"")
|
||||
out.RawString(hex.EncodeToString(in.Sig[:]) + "\"")
|
||||
out.RawString(HexEncodeToString(in.Sig[:]) + "\"")
|
||||
}
|
||||
|
||||
out.RawByte('}')
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func TestEventParsingAndVerifying(t *testing.T) {
|
||||
@@ -36,7 +36,7 @@ func TestEventParsingAndVerifying(t *testing.T) {
|
||||
|
||||
func TestEventSerialization(t *testing.T) {
|
||||
sig := [64]byte{}
|
||||
hex.Decode(sig[:], []byte("ed08d2dd5b0f7b6a3cdc74643d4adee3158ddede9cc848e8cd97630c097001acc2d052d2d3ec2b7ac4708b2314b797106d1b3c107322e61b5e5cc2116e099b79"))
|
||||
xhex.Decode(sig[:], []byte("ed08d2dd5b0f7b6a3cdc74643d4adee3158ddede9cc848e8cd97630c097001acc2d052d2d3ec2b7ac4708b2314b797106d1b3c107322e61b5e5cc2116e099b79"))
|
||||
|
||||
events := []Event{
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package bluge
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,6 +22,6 @@ func (id eventIdentifier) Field() string {
|
||||
|
||||
func (id eventIdentifier) Term() []byte {
|
||||
idhex := make([]byte, 64)
|
||||
hex.Encode(idhex, id[:])
|
||||
xhex.Encode(idhex, id[:])
|
||||
return idhex
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ package boltdb
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"slices"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore/codec/betterbinary"
|
||||
"fiatjaf.com/nostr/nip45"
|
||||
"fiatjaf.com/nostr/nip45/hyperloglog"
|
||||
"github.com/templexxx/xhex"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
@@ -174,11 +174,11 @@ func (b *BoltBackend) countEventsHLLCached(filter nostr.Filter) (uint32, *hyperl
|
||||
binary.BigEndian.PutUint16(cacheKey[0:2], uint16(filter.Kinds[0]))
|
||||
switch filter.Kinds[0] {
|
||||
case 3:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["p"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["p"][0][0:8*2]))
|
||||
case 7:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["e"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["e"][0][0:8*2]))
|
||||
case 1111:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["E"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["E"][0][0:8*2]))
|
||||
}
|
||||
|
||||
var count uint32
|
||||
@@ -204,7 +204,7 @@ func (b *BoltBackend) updateHyperLogLogCachedValues(txn *bbolt.Tx, evt nostr.Eve
|
||||
|
||||
for ref, offset := range nip45.HyperLogLogEventPubkeyOffsetsAndReferencesForEvent(evt) {
|
||||
// setup cache key (reusing buffer)
|
||||
hex.Decode(cacheKey[2:2+8], []byte(ref[0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(ref[0:8*2]))
|
||||
|
||||
// fetch hll value from cache db
|
||||
hll := hyperloglog.New(offset)
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/templexxx/xhex"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
@@ -284,7 +284,7 @@ func (b *BoltBackend) getTagIndexPrefix(tagName string, tagValue string) (bucket
|
||||
if len(tagValue) == 64 {
|
||||
// but we actually only use the first 8 bytes, with letter (tag name) prefix
|
||||
k = make([]byte, 1+8+4+8)
|
||||
if _, err := hex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
k[0] = letterPrefix
|
||||
return indexTag32, k
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func (b *BoltBackend) getTagIndexPrefix(tagName string, tagValue string) (bucket
|
||||
spl := strings.Split(tagValue, ":")
|
||||
if len(spl) == 3 && len(spl[1]) == 64 {
|
||||
k = make([]byte, 1+2+8+30+4+8)
|
||||
if _, err := hex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if kind, err := strconv.ParseUint(spl[0], 10, 16); err == nil {
|
||||
k[0] = letterPrefix
|
||||
k[1] = byte(kind >> 8)
|
||||
|
||||
@@ -3,7 +3,6 @@ package lmdb
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"slices"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
@@ -11,6 +10,7 @@ import (
|
||||
"fiatjaf.com/nostr/nip45"
|
||||
"fiatjaf.com/nostr/nip45/hyperloglog"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func (b *LMDBBackend) CountEvents(filter nostr.Filter) (uint32, error) {
|
||||
@@ -185,11 +185,11 @@ func (b *LMDBBackend) countEventsHLLCached(filter nostr.Filter) (uint32, *hyperl
|
||||
binary.BigEndian.PutUint16(cacheKey[0:2], uint16(filter.Kinds[0]))
|
||||
switch filter.Kinds[0] {
|
||||
case 3:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["p"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["p"][0][0:8*2]))
|
||||
case 7:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["e"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["e"][0][0:8*2]))
|
||||
case 1111:
|
||||
hex.Decode(cacheKey[2:2+8], []byte(filter.Tags["E"][0][0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(filter.Tags["E"][0][0:8*2]))
|
||||
}
|
||||
|
||||
var count uint32
|
||||
@@ -217,7 +217,7 @@ func (b *LMDBBackend) updateHyperLogLogCachedValues(txn *lmdb.Txn, evt nostr.Eve
|
||||
|
||||
for ref, offset := range nip45.HyperLogLogEventPubkeyOffsetsAndReferencesForEvent(evt) {
|
||||
// setup cache key (reusing buffer)
|
||||
hex.Decode(cacheKey[2:2+8], []byte(ref[0:8*2]))
|
||||
xhex.Decode(cacheKey[2:2+8], []byte(ref[0:8*2]))
|
||||
|
||||
// fetch hll value from cache db
|
||||
hll := hyperloglog.New(offset)
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
@@ -13,6 +12,7 @@ import (
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
type iterator struct {
|
||||
@@ -244,7 +244,7 @@ func (b *LMDBBackend) getIndexKeysForEvent(evt nostr.Event) iter.Seq[key] {
|
||||
// now the p-tag+kind+date
|
||||
if dbi == b.indexTag32 && tag[0] == "p" {
|
||||
k := make([]byte, 8+2+4)
|
||||
hex.Decode(k[0:8], []byte(tag[1][0:8*2]))
|
||||
xhex.Decode(k[0:8], []byte(tag[1][0:8*2]))
|
||||
binary.BigEndian.PutUint16(k[8:8+2], uint16(evt.Kind))
|
||||
binary.BigEndian.PutUint32(k[8+2:8+2+4], uint32(evt.CreatedAt))
|
||||
dbi := b.indexPTagKind
|
||||
@@ -276,7 +276,7 @@ func (b *LMDBBackend) getTagIndexPrefix(tagName string, tagValue string) (lmdb.D
|
||||
if len(tagValue) == 64 {
|
||||
// but we actually only use the first 8 bytes, with letter (tag name) prefix
|
||||
k = make([]byte, 1+8+4)
|
||||
if _, err := hex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
k[0] = letterPrefix
|
||||
offset = 1 + 8
|
||||
dbi = b.indexTag32
|
||||
@@ -288,7 +288,7 @@ func (b *LMDBBackend) getTagIndexPrefix(tagName string, tagValue string) (lmdb.D
|
||||
spl := strings.Split(tagValue, ":")
|
||||
if len(spl) == 3 && len(spl[1]) == 64 {
|
||||
k = make([]byte, 1+2+8+30+4)
|
||||
if _, err := hex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if kind, err := strconv.ParseUint(spl[0], 10, 16); err == nil {
|
||||
k[0] = letterPrefix
|
||||
k[1] = byte(kind >> 8)
|
||||
|
||||
@@ -2,12 +2,12 @@ package lmdb
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore/internal"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
type query struct {
|
||||
@@ -76,7 +76,7 @@ func (b *LMDBBackend) prepareQueries(filter nostr.Filter) (
|
||||
|
||||
for _, kind := range filter.Kinds {
|
||||
k := make([]byte, 8+2)
|
||||
if _, err := hex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
if err := xhex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
return nil, nil, nil, "", nil, 0, fmt.Errorf("invalid 'p' tag '%s'", value)
|
||||
}
|
||||
binary.BigEndian.PutUint16(k[8:8+2], uint16(kind))
|
||||
@@ -93,7 +93,7 @@ func (b *LMDBBackend) prepareQueries(filter nostr.Filter) (
|
||||
}
|
||||
|
||||
k := make([]byte, 8)
|
||||
if _, err := hex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
if err := xhex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
return nil, nil, nil, "", nil, 0, fmt.Errorf("invalid 'p' tag '%s'", value)
|
||||
}
|
||||
queries[i] = query{i: i, dbi: b.indexPTagKind, prefix: k[0:8], keySize: 8 + 2 + 4}
|
||||
|
||||
@@ -3,7 +3,6 @@ package mmm
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"iter"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -11,6 +10,7 @@ import (
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
type iterator struct {
|
||||
@@ -229,7 +229,7 @@ func (il *IndexingLayer) getIndexKeysForEvent(evt nostr.Event) iter.Seq[key] {
|
||||
// now the p-tag+kind+date
|
||||
if dbi == il.indexTag32 && tag[0] == "p" {
|
||||
k := make([]byte, 8+2+4)
|
||||
hex.Decode(k[0:8], []byte(tag[1][0:8*2]))
|
||||
xhex.Decode(k[0:8], []byte(tag[1][0:8*2]))
|
||||
binary.BigEndian.PutUint16(k[8:8+2], uint16(evt.Kind))
|
||||
binary.BigEndian.PutUint32(k[8+2:8+2+4], uint32(evt.CreatedAt))
|
||||
dbi := il.indexPTagKind
|
||||
@@ -261,7 +261,7 @@ func (il *IndexingLayer) getTagIndexPrefix(tagName string, tagValue string) (lmd
|
||||
if len(tagValue) == 64 {
|
||||
// but we actually only use the first 8 bytes, with letter (tag name) prefix
|
||||
k = make([]byte, 1+8+4)
|
||||
if _, err := hex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1:1+8], []byte(tagValue[0:8*2])); err == nil {
|
||||
k[0] = letterPrefix
|
||||
offset = 1 + 8
|
||||
dbi = il.indexTag32
|
||||
@@ -273,7 +273,7 @@ func (il *IndexingLayer) getTagIndexPrefix(tagName string, tagValue string) (lmd
|
||||
spl := strings.Split(tagValue, ":")
|
||||
if len(spl) == 3 && len(spl[1]) == 64 {
|
||||
k = make([]byte, 1+2+8+30+4)
|
||||
if _, err := hex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if err := xhex.Decode(k[1+2:1+2+8], []byte(spl[1][0:8*2])); err == nil {
|
||||
if kind, err := strconv.ParseUint(spl[0], 10, 16); err == nil {
|
||||
k[0] = letterPrefix
|
||||
k[1] = byte(kind >> 8)
|
||||
|
||||
@@ -2,12 +2,12 @@ package mmm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore/internal"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
type query struct {
|
||||
@@ -77,7 +77,7 @@ func (il *IndexingLayer) prepareQueries(filter nostr.Filter) (
|
||||
|
||||
for _, kind := range filter.Kinds {
|
||||
k := make([]byte, 8+2)
|
||||
if _, err := hex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
if err := xhex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
return nil, nil, nil, "", nil, 0, fmt.Errorf("invalid 'p' tag '%s'", value)
|
||||
}
|
||||
binary.BigEndian.PutUint16(k[8:8+2], uint16(kind))
|
||||
@@ -94,7 +94,7 @@ func (il *IndexingLayer) prepareQueries(filter nostr.Filter) (
|
||||
}
|
||||
|
||||
k := make([]byte, 8)
|
||||
if _, err := hex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
if err := xhex.Decode(k[0:8], []byte(value[0:8*2])); err != nil {
|
||||
return nil, nil, nil, "", nil, 0, fmt.Errorf("invalid 'p' tag '%s'", value)
|
||||
}
|
||||
queries[i] = query{i: i, dbi: il.indexPTagKind, prefix: k[0:8], keySize: 8 + 2 + 4, timestampSize: 4}
|
||||
|
||||
@@ -2,7 +2,6 @@ package test
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -42,7 +41,7 @@ func runBenchmarkOn(b *testing.B, db eventstore.Store) {
|
||||
Content: fmt.Sprintf("hello %d", i),
|
||||
Tags: nostr.Tags{
|
||||
{"t", fmt.Sprintf("t%d", i)},
|
||||
{"e", hex.EncodeToString(eTag)},
|
||||
{"e", nostr.HexEncodeToString(eTag)},
|
||||
{"p", ref.Hex()},
|
||||
},
|
||||
Kind: nostr.Kind(i % 10),
|
||||
@@ -70,7 +69,7 @@ func runBenchmarkOn(b *testing.B, db eventstore.Store) {
|
||||
for i := 0; i < 20; i++ {
|
||||
eTag := make([]byte, 32)
|
||||
binary.BigEndian.PutUint16(eTag, uint16(i))
|
||||
eTags[i] = hex.EncodeToString(eTag)
|
||||
eTags[i] = nostr.HexEncodeToString(eTag)
|
||||
}
|
||||
filters = append(filters, nostr.Filter{Kinds: []nostr.Kind{9}, Tags: nostr.TagMap{"e": eTags}})
|
||||
filters = append(filters, nostr.Filter{Kinds: []nostr.Kind{5}, Tags: nostr.TagMap{"e": eTags, "t": []string{"t5"}}})
|
||||
|
||||
@@ -2,7 +2,6 @@ package test
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"slices"
|
||||
"testing"
|
||||
@@ -29,7 +28,7 @@ func runSecondTestOn(t *testing.T, db eventstore.Store) {
|
||||
Content: fmt.Sprintf("hello %d", i),
|
||||
Tags: nostr.Tags{
|
||||
{"t", fmt.Sprintf("t%d", i)},
|
||||
{"e", hex.EncodeToString(eTag)},
|
||||
{"e", nostr.HexEncodeToString(eTag)},
|
||||
{"p", ref.Hex()},
|
||||
},
|
||||
Kind: nostr.Kind(i % 10),
|
||||
@@ -49,7 +48,7 @@ func runSecondTestOn(t *testing.T, db eventstore.Store) {
|
||||
for i := 0; i < 20; i++ {
|
||||
eTag := make([]byte, 32)
|
||||
binary.BigEndian.PutUint16(eTag, uint16(i))
|
||||
eTags[i] = hex.EncodeToString(eTag)
|
||||
eTags[i] = nostr.HexEncodeToString(eTag)
|
||||
}
|
||||
|
||||
filters := []nostr.Filter{
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func easyjsonDecodeFilter(in *jlexer.Lexer, out *Filter) {
|
||||
@@ -42,7 +41,7 @@ func easyjsonDecodeFilter(in *jlexer.Lexer, out *Filter) {
|
||||
id := ID{}
|
||||
b := in.UnsafeBytes()
|
||||
if len(b) == 64 {
|
||||
hex.Decode(id[:], b)
|
||||
xhex.Decode(id[:], b)
|
||||
}
|
||||
out.IDs = append(out.IDs, id)
|
||||
in.WantComma()
|
||||
@@ -79,7 +78,7 @@ func easyjsonDecodeFilter(in *jlexer.Lexer, out *Filter) {
|
||||
pk := PubKey{}
|
||||
b := in.UnsafeBytes()
|
||||
if len(b) == 64 {
|
||||
hex.Decode(pk[:], b)
|
||||
xhex.Decode(pk[:], b)
|
||||
}
|
||||
out.Authors = append(out.Authors, pk)
|
||||
in.WantComma()
|
||||
@@ -140,7 +139,7 @@ func easyjsonEncodeFilter(out *jwriter.Writer, in Filter) {
|
||||
if i > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.RawString("\"" + hex.EncodeToString(id[:]) + "\"")
|
||||
out.RawString("\"" + HexEncodeToString(id[:]) + "\"")
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
@@ -178,7 +177,7 @@ func easyjsonEncodeFilter(out *jwriter.Writer, in Filter) {
|
||||
if i > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.RawString("\"" + hex.EncodeToString(pk[:]) + "\"")
|
||||
out.RawString("\"" + HexEncodeToString(pk[:]) + "\"")
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -43,6 +43,8 @@ require (
|
||||
require (
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0
|
||||
github.com/go-git/go-git/v5 v5.16.3
|
||||
github.com/templexxx/cpu v0.0.1
|
||||
github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
4
go.sum
4
go.sum
@@ -247,6 +247,10 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||
github.com/templexxx/cpu v0.0.1 h1:hY4WdLOgKdc8y13EYklu9OUTXik80BkxHoWvTO6MQQY=
|
||||
github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
|
||||
github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b h1:XeDLE6c9mzHpdv3Wb1+pWBaWv/BlHK0ZYIu/KaL6eHg=
|
||||
github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b/go.mod h1:7rwmCH0wC2fQvNEvPZ3sKXukhyCTyiaZ5VTZMQYpZKQ=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/templexxx/xhex"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
@@ -186,7 +186,7 @@ func extractEventID(jsonStr string) ID {
|
||||
|
||||
// get 64 characters of the id
|
||||
var id [32]byte
|
||||
hex.Decode(id[:], unsafe.Slice(unsafe.StringData(jsonStr[start:start+64]), 64))
|
||||
xhex.Decode(id[:], unsafe.Slice(unsafe.StringData(jsonStr[start:start+64]), 64))
|
||||
return id
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func extractEventPubKey(jsonStr string) PubKey {
|
||||
|
||||
// get 64 characters of the pubkey
|
||||
var pk [32]byte
|
||||
hex.Decode(pk[:], unsafe.Slice(unsafe.StringData(jsonStr[start:start+64]), 64))
|
||||
xhex.Decode(pk[:], unsafe.Slice(unsafe.StringData(jsonStr[start:start+64]), 64))
|
||||
return pk
|
||||
}
|
||||
|
||||
|
||||
26
keys.go
26
keys.go
@@ -2,7 +2,6 @@ package nostr
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
stdjson "encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -11,6 +10,7 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
var KeyOne = SecretKey{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||
@@ -36,11 +36,11 @@ func Generate() SecretKey {
|
||||
type SecretKey [32]byte
|
||||
|
||||
func (sk SecretKey) String() string { return "sk::" + sk.Hex() }
|
||||
func (sk SecretKey) Hex() string { return hex.EncodeToString(sk[:]) }
|
||||
func (sk SecretKey) Hex() string { return HexEncodeToString(sk[:]) }
|
||||
func (sk SecretKey) Public() PubKey { return GetPublicKey(sk) }
|
||||
func (pk SecretKey) MarshalJSON() ([]byte, error) {
|
||||
res := make([]byte, 66)
|
||||
hex.Encode(res[1:], pk[:])
|
||||
xhex.Encode(res[1:], pk[:])
|
||||
res[0] = '"'
|
||||
res[65] = '"'
|
||||
return res, nil
|
||||
@@ -50,7 +50,7 @@ func (pk *SecretKey) UnmarshalJSON(buf []byte) error {
|
||||
if len(buf) != 66 {
|
||||
return fmt.Errorf("must be a hex string of 64 characters")
|
||||
}
|
||||
if _, err := hex.Decode(pk[:], buf[1:65]); err != nil {
|
||||
if err := xhex.Decode(pk[:], buf[1:65]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -65,7 +65,7 @@ func SecretKeyFromHex(skh string) (SecretKey, error) {
|
||||
return sk, fmt.Errorf("secret key should be at most 64-char hex, got '%s'", skh)
|
||||
}
|
||||
|
||||
if _, err := hex.Decode(sk[:], unsafe.Slice(unsafe.StringData(skh), 64)); err != nil {
|
||||
if err := xhex.Decode(sk[:], unsafe.Slice(unsafe.StringData(skh), 64)); err != nil {
|
||||
return sk, fmt.Errorf("'%s' is not valid hex: %w", skh, err)
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func SecretKeyFromHex(skh string) (SecretKey, error) {
|
||||
|
||||
func MustSecretKeyFromHex(idh string) SecretKey {
|
||||
id := SecretKey{}
|
||||
if _, err := hex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
if err := xhex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
@@ -107,10 +107,10 @@ var (
|
||||
)
|
||||
|
||||
func (pk PubKey) String() string { return "pk::" + pk.Hex() }
|
||||
func (pk PubKey) Hex() string { return hex.EncodeToString(pk[:]) }
|
||||
func (pk PubKey) Hex() string { return HexEncodeToString(pk[:]) }
|
||||
func (pk PubKey) MarshalJSON() ([]byte, error) {
|
||||
res := make([]byte, 66)
|
||||
hex.Encode(res[1:], pk[:])
|
||||
xhex.Encode(res[1:], pk[:])
|
||||
res[0] = '"'
|
||||
res[65] = '"'
|
||||
return res, nil
|
||||
@@ -120,7 +120,7 @@ func (pk *PubKey) UnmarshalJSON(buf []byte) error {
|
||||
if len(buf) != 66 {
|
||||
return fmt.Errorf("must be a hex string of 64 characters")
|
||||
}
|
||||
if _, err := hex.Decode(pk[:], buf[1:65]); err != nil {
|
||||
if err := xhex.Decode(pk[:], buf[1:65]); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := schnorr.ParsePubKey(pk[:]); err != nil {
|
||||
@@ -134,7 +134,7 @@ func PubKeyFromHex(pkh string) (PubKey, error) {
|
||||
if len(pkh) != 64 {
|
||||
return pk, fmt.Errorf("pubkey should be 64-char hex, got '%s'", pkh)
|
||||
}
|
||||
if _, err := hex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64)); err != nil {
|
||||
if err := xhex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64)); err != nil {
|
||||
return pk, fmt.Errorf("'%s' is not valid hex: %w", pkh, err)
|
||||
}
|
||||
if _, err := schnorr.ParsePubKey(pk[:]); err != nil {
|
||||
@@ -148,7 +148,7 @@ func PubKeyFromHexCheap(pkh string) (PubKey, error) {
|
||||
if len(pkh) != 64 {
|
||||
return pk, fmt.Errorf("pubkey should be 64-char hex, got '%s'", pkh)
|
||||
}
|
||||
if _, err := hex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64)); err != nil {
|
||||
if err := xhex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64)); err != nil {
|
||||
return pk, fmt.Errorf("'%s' is not valid hex: %w", pkh, err)
|
||||
}
|
||||
|
||||
@@ -157,7 +157,9 @@ func PubKeyFromHexCheap(pkh string) (PubKey, error) {
|
||||
|
||||
func MustPubKeyFromHex(pkh string) PubKey {
|
||||
pk := PubKey{}
|
||||
hex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64))
|
||||
if err := xhex.Decode(pk[:], unsafe.Slice(unsafe.StringData(pkh), 64)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package blossom
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"mime"
|
||||
@@ -128,7 +127,7 @@ func (bs BlossomServer) handleUpload(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(b)
|
||||
hhash := hex.EncodeToString(hash[:])
|
||||
hhash := nostr.HexEncodeToString(hash[:])
|
||||
mimeType := mime.TypeByExtension(ext)
|
||||
if mimeType == "" {
|
||||
mimeType = "application/octet-stream"
|
||||
@@ -443,7 +442,7 @@ func (bs BlossomServer) handleMirror(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// calculate sha256
|
||||
hash := sha256.Sum256(body)
|
||||
hhash := hex.EncodeToString(hash[:])
|
||||
hhash := nostr.HexEncodeToString(hash[:])
|
||||
|
||||
// verify hash against x tag
|
||||
if auth.Tags.FindWithValue("x", hhash) == nil {
|
||||
|
||||
@@ -3,7 +3,6 @@ package khatru
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net/http"
|
||||
"slices"
|
||||
@@ -76,7 +75,7 @@ func (rl *Relay) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
|
||||
ws := &WebSocket{
|
||||
conn: conn,
|
||||
Request: r,
|
||||
Challenge: rl.ChallengePrefix + hex.EncodeToString(challenge),
|
||||
Challenge: rl.ChallengePrefix + nostr.HexEncodeToString(challenge),
|
||||
AuthedPublicKeys: make([]nostr.PubKey, 0),
|
||||
negentropySessions: xsync.NewMapOf[string, *NegentropySession](),
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -99,7 +98,7 @@ func (rl *Relay) HandleNIP86(w http.ResponseWriter, r *http.Request) {
|
||||
goto respond
|
||||
}
|
||||
|
||||
if pht := evt.Tags.FindWithValue("payload", hex.EncodeToString(payloadHash[:])); pht == nil {
|
||||
if pht := evt.Tags.FindWithValue("payload", nostr.HexEncodeToString(payloadHash[:])); pht == nil {
|
||||
resp.Error = "invalid auth event payload hash"
|
||||
goto respond
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -23,7 +22,7 @@ func ComputeSharedSecret(pub nostr.PubKey, sk [32]byte) (sharedSecret []byte, er
|
||||
// adding 02 to signal that this is a compressed public key (33 bytes)
|
||||
pubKey, err := btcec.ParsePubKey(append([]byte{2}, pub[:]...))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing receiver public key '%s': %w", "02"+hex.EncodeToString(pub[:]), err)
|
||||
return nil, fmt.Errorf("error parsing receiver public key '%s': %w", "02"+nostr.HexEncodeToString(pub[:]), err)
|
||||
}
|
||||
|
||||
return btcec.GenerateSharedSecret(privKey, pubKey), nil
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package nip04
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -56,8 +55,8 @@ func TestEncryptionAndDecryptionWithMultipleLengths(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNostrToolsCompatibility(t *testing.T) {
|
||||
sk1, _ := hex.DecodeString("92996316beebf94171065a714cbf164d1f56d7ad9b35b329d9fc97535bf25352")
|
||||
sk2, _ := hex.DecodeString("591c0c249adfb9346f8d37dfeed65725e2eea1d7a6e99fa503342f367138de84")
|
||||
sk1, _ := nostr.HexDecodeString("92996316beebf94171065a714cbf164d1f56d7ad9b35b329d9fc97535bf25352")
|
||||
sk2, _ := nostr.HexDecodeString("591c0c249adfb9346f8d37dfeed65725e2eea1d7a6e99fa503342f367138de84")
|
||||
pk2 := nostr.GetPublicKey([32]byte(sk2))
|
||||
shared, _ := ComputeSharedSecret(pk2, [32]byte(sk1))
|
||||
ciphertext := "A+fRnU4aXS4kbTLfowqAww==?iv=QFYUrl5or/n/qamY79ze0A=="
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package nip06
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/tyler-smith/go-bip32"
|
||||
"github.com/tyler-smith/go-bip39"
|
||||
)
|
||||
@@ -47,7 +46,7 @@ func PrivateKeyFromSeed(seed []byte) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return hex.EncodeToString(next.Key), nil
|
||||
return nostr.HexEncodeToString(next.Key), nil
|
||||
}
|
||||
|
||||
func ValidateWords(words string) bool {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package nip19
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func TestEncodeNpub(t *testing.T) {
|
||||
@@ -17,7 +17,7 @@ func TestEncodeNpub(t *testing.T) {
|
||||
func TestEncodeNsec(t *testing.T) {
|
||||
skh := "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"
|
||||
var sk [32]byte
|
||||
hex.Decode(sk[:], []byte(skh))
|
||||
xhex.Decode(sk[:], []byte(skh))
|
||||
nsec := EncodeNsec(sk)
|
||||
assert.Equal(t, "nsec180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsgyumg0", nsec, "produced an unexpected nsec string")
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -162,7 +161,7 @@ func Decrypt(b64ciphertextWrapped string, conversationKey [32]byte) (string, err
|
||||
return string(unpadded), nil
|
||||
}
|
||||
|
||||
var maxThreshold, _ = hex.DecodeString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
|
||||
var maxThreshold, _ = nostr.HexDecodeString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
|
||||
|
||||
func GenerateConversationKey(pub nostr.PubKey, sk nostr.SecretKey) ([32]byte, error) {
|
||||
var ck [32]byte
|
||||
@@ -236,7 +235,7 @@ func computeSharedSecret(pub nostr.PubKey, sk [32]byte) (sharedSecret [32]byte,
|
||||
pubKey, err := btcec.ParsePubKey(append([]byte{2}, pub[:]...))
|
||||
if err != nil {
|
||||
return sharedSecret, fmt.Errorf("error parsing receiver public key '%s': %w",
|
||||
"02"+hex.EncodeToString(pub[:]), err)
|
||||
"02"+nostr.HexEncodeToString(pub[:]), err)
|
||||
}
|
||||
|
||||
var point, result secp256k1.JacobianPoint
|
||||
|
||||
@@ -2,12 +2,12 @@ package nip44
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func assertCryptPriv(t *testing.T, skh1 string, skh2 string, conversationKey string, salt string, plaintext string, expected string) {
|
||||
@@ -19,7 +19,7 @@ func assertCryptPriv(t *testing.T, skh1 string, skh2 string, conversationKey str
|
||||
|
||||
assertConversationKeyGenerationPub(t, skh1, pub2.Hex(), conversationKey)
|
||||
|
||||
customNonce, err := hex.DecodeString(salt)
|
||||
customNonce, err := nostr.HexDecodeString(salt)
|
||||
require.NoErrorf(t, err, "hex decode failed for salt: %v", err)
|
||||
|
||||
actual, err := Encrypt(plaintext, k1, WithCustomNonce(customNonce))
|
||||
@@ -70,13 +70,13 @@ func assertMessageKeyGeneration(t *testing.T, conversationKey string, salt strin
|
||||
convNonce, err := hexDecode32Array(salt)
|
||||
require.NoErrorf(t, err, "hex decode failed for nonce: %v", err)
|
||||
|
||||
expectedChaChaKey, err := hex.DecodeString(chachaKey)
|
||||
expectedChaChaKey, err := nostr.HexDecodeString(chachaKey)
|
||||
require.NoErrorf(t, err, "hex decode failed for chacha key: %v", err)
|
||||
|
||||
expectedChaChaNonce, err := hex.DecodeString(chachaSalt)
|
||||
expectedChaChaNonce, err := nostr.HexDecodeString(chachaSalt)
|
||||
require.NoErrorf(t, err, "hex decode failed for chacha nonce: %v", err)
|
||||
|
||||
expectedHmacKey, err := hex.DecodeString(hmacKey)
|
||||
expectedHmacKey, err := nostr.HexDecodeString(hmacKey)
|
||||
require.NoErrorf(t, err, "hex decode failed for hmac key: %v", err)
|
||||
|
||||
actualChaChaKey, actualChaChaNonce, actualHmacKey, err := messageKeys(convKey, convNonce)
|
||||
@@ -92,7 +92,7 @@ func assertCryptLong(t *testing.T, conversationKey string, salt string, pattern
|
||||
convKey, err := hexDecode32Array(conversationKey)
|
||||
require.NoErrorf(t, err, "hex decode failed for convKey: %v", err)
|
||||
|
||||
customNonce, err := hex.DecodeString(salt)
|
||||
customNonce, err := nostr.HexDecodeString(salt)
|
||||
require.NoErrorf(t, err, "hex decode failed for salt: %v", err)
|
||||
|
||||
plaintext := ""
|
||||
@@ -101,7 +101,7 @@ func assertCryptLong(t *testing.T, conversationKey string, salt string, pattern
|
||||
}
|
||||
h := sha256.New()
|
||||
h.Write([]byte(plaintext))
|
||||
actualPlaintextSha256 := hex.EncodeToString(h.Sum(nil))
|
||||
actualPlaintextSha256 := nostr.HexEncodeToString(h.Sum(nil))
|
||||
require.Equalf(t, plaintextSha256, actualPlaintextSha256, "invalid plaintext sha256 hash: %v", err)
|
||||
|
||||
actualPayload, err := Encrypt(plaintext, convKey, WithCustomNonce(customNonce))
|
||||
@@ -109,7 +109,7 @@ func assertCryptLong(t *testing.T, conversationKey string, salt string, pattern
|
||||
|
||||
h.Reset()
|
||||
h.Write([]byte(actualPayload))
|
||||
actualPayloadSha256 := hex.EncodeToString(h.Sum(nil))
|
||||
actualPayloadSha256 := nostr.HexEncodeToString(h.Sum(nil))
|
||||
require.Equalf(t, payloadSha256, actualPayloadSha256, "invalid payload sha256 hash: %v", err)
|
||||
}
|
||||
|
||||
@@ -1051,7 +1051,7 @@ func TestMessageKeyGeneration033(t *testing.T) {
|
||||
}
|
||||
|
||||
func hexDecode32Array(hexString string) (res [32]byte, err error) {
|
||||
_, err = hex.Decode(res[:], []byte(hexString))
|
||||
err = xhex.Decode(res[:], []byte(hexString))
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package nip46
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
@@ -56,7 +55,7 @@ func ConnectBunker(
|
||||
pool,
|
||||
onAuth,
|
||||
)
|
||||
_, err = bunker.RPC(ctx, "connect", []string{hex.EncodeToString(parsed.HostPubKey[:]), parsed.Secret})
|
||||
_, err = bunker.RPC(ctx, "connect", []string{nostr.HexEncodeToString(parsed.HostPubKey[:]), parsed.Secret})
|
||||
return bunker, err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package nip46
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
@@ -131,7 +130,7 @@ func (p *DynamicSigner) HandleRequest(ctx context.Context, event nostr.Event) (
|
||||
|
||||
result = "ack"
|
||||
case "get_public_key":
|
||||
result = hex.EncodeToString(session.PublicKey[:])
|
||||
result = nostr.HexEncodeToString(session.PublicKey[:])
|
||||
case "sign_event":
|
||||
if len(req.Params) != 1 {
|
||||
resultErr = fmt.Errorf("wrong number of arguments to 'sign_event'")
|
||||
|
||||
@@ -2,7 +2,6 @@ package nip46
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
@@ -90,7 +89,7 @@ func (p *StaticKeySigner) HandleRequest(_ context.Context, event nostr.Event) (
|
||||
result = "ack"
|
||||
harmless = true
|
||||
case "get_public_key":
|
||||
result = hex.EncodeToString(session.PublicKey[:])
|
||||
result = nostr.HexEncodeToString(session.PublicKey[:])
|
||||
harmless = true
|
||||
case "sign_event":
|
||||
if len(req.Params) != 1 {
|
||||
|
||||
@@ -3,13 +3,13 @@ package nip60
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
@@ -66,7 +66,7 @@ func createBlindedMessages(
|
||||
if _, err := rand.Read(secretBytes); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
secret = hex.EncodeToString(secretBytes)
|
||||
secret = nostr.HexEncodeToString(secretBytes)
|
||||
}
|
||||
|
||||
B_, r, err := crypto.BlindMessage(secret, r)
|
||||
@@ -92,7 +92,7 @@ func signInput(
|
||||
return "", fmt.Errorf("failed to sign: %w", err)
|
||||
}
|
||||
witness, _ := json.Marshal(nut11.P2PKWitness{
|
||||
Signatures: []string{hex.EncodeToString(signature.Serialize())},
|
||||
Signatures: []string{nostr.HexEncodeToString(signature.Serialize())},
|
||||
})
|
||||
return string(witness), nil
|
||||
}
|
||||
@@ -101,14 +101,14 @@ func signOutput(
|
||||
privateKey *btcec.PrivateKey,
|
||||
output cashu.BlindedMessage,
|
||||
) (string, error) {
|
||||
msg, _ := hex.DecodeString(output.B_)
|
||||
msg, _ := nostr.HexDecodeString(output.B_)
|
||||
hash := sha256.Sum256(msg)
|
||||
signature, err := schnorr.Sign(privateKey, hash[:])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to sign: %w", err)
|
||||
}
|
||||
witness, _ := json.Marshal(nut11.P2PKWitness{
|
||||
Signatures: []string{hex.EncodeToString(signature.Serialize())},
|
||||
Signatures: []string{nostr.HexEncodeToString(signature.Serialize())},
|
||||
})
|
||||
return string(witness), nil
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func constructProofs(
|
||||
dleq = &cashu.DLEQProof{
|
||||
E: blindedSignature.DLEQ.E,
|
||||
S: blindedSignature.DLEQ.S,
|
||||
R: hex.EncodeToString(prep.rs[i].Serialize()),
|
||||
R: nostr.HexEncodeToString(prep.rs[i].Serialize()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ func unblindSignature(C_str string, r *secp256k1.PrivateKey, key *secp256k1.Publ
|
||||
string,
|
||||
error,
|
||||
) {
|
||||
C_bytes, err := hex.DecodeString(C_str)
|
||||
C_bytes, err := nostr.HexDecodeString(C_str)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -180,14 +180,14 @@ func unblindSignature(C_str string, r *secp256k1.PrivateKey, key *secp256k1.Publ
|
||||
}
|
||||
|
||||
C := crypto.UnblindSignature(C_, r, key)
|
||||
Cstr := hex.EncodeToString(C.SerializeCompressed())
|
||||
Cstr := nostr.HexEncodeToString(C.SerializeCompressed())
|
||||
return Cstr, nil
|
||||
}
|
||||
|
||||
func ParseKeysetKeys(keys nut01.KeysMap) (map[uint64]*btcec.PublicKey, error) {
|
||||
parsedKeys := make(map[uint64]*btcec.PublicKey)
|
||||
for amount, pkh := range keys {
|
||||
pkb, err := hex.DecodeString(pkh)
|
||||
pkb, err := nostr.HexDecodeString(pkh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package nip60
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
@@ -42,7 +41,7 @@ func (opts SendOptions) asSpendingCondition(refund *btcec.PublicKey) *nut10.Spen
|
||||
|
||||
return &nut10.SpendingCondition{
|
||||
Kind: nut10.HTLC,
|
||||
Data: hex.EncodeToString(opts.Hashlock[:]),
|
||||
Data: nostr.HexEncodeToString(opts.Hashlock[:]),
|
||||
Tags: nut11.SerializeP2PKTags(tags),
|
||||
}
|
||||
} else if opts.P2PK != nil {
|
||||
@@ -62,7 +61,7 @@ func (opts SendOptions) asSpendingCondition(refund *btcec.PublicKey) *nut10.Spen
|
||||
|
||||
return &nut10.SpendingCondition{
|
||||
Kind: nut10.P2PK,
|
||||
Data: hex.EncodeToString(opts.P2PK.SerializeCompressed()),
|
||||
Data: nostr.HexEncodeToString(opts.P2PK.SerializeCompressed()),
|
||||
Tags: nut11.SerializeP2PKTags(tags),
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@ package nip60
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
@@ -344,7 +343,7 @@ func (w *Wallet) SetPrivateKey(ctx context.Context, privateKey string) error {
|
||||
return fmt.Errorf("can't do write operations: missing PublishUpdate function")
|
||||
}
|
||||
|
||||
skb, err := hex.DecodeString(privateKey)
|
||||
skb, err := nostr.HexDecodeString(privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -378,7 +377,7 @@ func (w *Wallet) toEvent(ctx context.Context, kr nostr.Keyer, evt *nostr.Event)
|
||||
|
||||
encryptedTags := make(nostr.Tags, 0, 1+len(w.Mints))
|
||||
if w.PrivateKey != nil {
|
||||
encryptedTags = append(encryptedTags, nostr.Tag{"privkey", hex.EncodeToString(w.PrivateKey.Serialize())})
|
||||
encryptedTags = append(encryptedTags, nostr.Tag{"privkey", nostr.HexEncodeToString(w.PrivateKey.Serialize())})
|
||||
}
|
||||
|
||||
for _, mint := range w.Mints {
|
||||
@@ -433,7 +432,7 @@ func (w *Wallet) parse(ctx context.Context, kr nostr.Keyer, evt *nostr.Event) er
|
||||
case "mint":
|
||||
mints = append(mints, tag[1])
|
||||
case "privkey":
|
||||
skb, err := hex.DecodeString(tag[1])
|
||||
skb, err := nostr.HexDecodeString(tag[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse private key: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package nip61
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
@@ -52,7 +51,7 @@ func verifyProofDLEQ(
|
||||
return false
|
||||
}
|
||||
|
||||
CBytes, err := hex.DecodeString(proof.C)
|
||||
CBytes, err := nostr.HexDecodeString(proof.C)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -88,7 +87,7 @@ func VerifyBlindSignatureDLEQ(
|
||||
return false
|
||||
}
|
||||
|
||||
B_bytes, err := hex.DecodeString(B_str)
|
||||
B_bytes, err := nostr.HexDecodeString(B_str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -97,7 +96,7 @@ func VerifyBlindSignatureDLEQ(
|
||||
return false
|
||||
}
|
||||
|
||||
C_bytes, err := hex.DecodeString(C_str)
|
||||
C_bytes, err := nostr.HexDecodeString(C_str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -115,13 +114,13 @@ func parseDLEQ(dleq cashu.DLEQProof) (
|
||||
*btcec.PrivateKey,
|
||||
error,
|
||||
) {
|
||||
ebytes, err := hex.DecodeString(dleq.E)
|
||||
ebytes, err := nostr.HexDecodeString(dleq.E)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
e := secp256k1.PrivKeyFromBytes(ebytes)
|
||||
|
||||
sbytes, err := hex.DecodeString(dleq.S)
|
||||
sbytes, err := nostr.HexDecodeString(dleq.S)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -131,7 +130,7 @@ func parseDLEQ(dleq cashu.DLEQProof) (
|
||||
return e, s, nil, nil
|
||||
}
|
||||
|
||||
rbytes, err := hex.DecodeString(dleq.R)
|
||||
rbytes, err := nostr.HexDecodeString(dleq.R)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package negentropy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -72,12 +71,12 @@ func (n *Negentropy) Start() string {
|
||||
output.WriteByte(protocolVersion)
|
||||
n.SplitRange(0, n.storage.Size(), InfiniteBound, output)
|
||||
|
||||
return hex.EncodeToString(output.Bytes())
|
||||
return nostr.HexEncodeToString(output.Bytes())
|
||||
}
|
||||
|
||||
func (n *Negentropy) Reconcile(msg string) (string, error) {
|
||||
n.initialized = true
|
||||
msgb, err := hex.DecodeString(msg)
|
||||
msgb, err := nostr.HexDecodeString(msg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -99,7 +98,7 @@ func (n *Negentropy) Reconcile(msg string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return hex.EncodeToString(output), nil
|
||||
return nostr.HexEncodeToString(output), nil
|
||||
}
|
||||
|
||||
func (n *Negentropy) reconcileAux(reader *bytes.Reader) ([]byte, error) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package blossom
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
@@ -16,7 +15,7 @@ func (c *Client) List(ctx context.Context) ([]BlobDescriptor, error) {
|
||||
}
|
||||
|
||||
bds := make([]BlobDescriptor, 0, 100)
|
||||
err = c.httpCall(ctx, "GET", "list/"+hex.EncodeToString(pubkey[:]), "", func() string {
|
||||
err = c.httpCall(ctx, "GET", "list/"+nostr.HexEncodeToString(pubkey[:]), "", func() string {
|
||||
return c.authorizationHeader(ctx, func(evt *nostr.Event) {
|
||||
evt.Tags = append(evt.Tags, nostr.Tag{"t", "list"})
|
||||
})
|
||||
|
||||
@@ -3,7 +3,6 @@ package blossom
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
@@ -47,7 +46,7 @@ func (c *Client) UploadBlob(ctx context.Context, file io.ReadSeeker, contentType
|
||||
err = c.httpCall(ctx, "PUT", "upload", contentType, func() string {
|
||||
return c.authorizationHeader(ctx, func(evt *nostr.Event) {
|
||||
evt.Tags = append(evt.Tags, nostr.Tag{"t", "upload"})
|
||||
evt.Tags = append(evt.Tags, nostr.Tag{"x", hex.EncodeToString(hash[:])})
|
||||
evt.Tags = append(evt.Tags, nostr.Tag{"x", nostr.HexEncodeToString(hash[:])})
|
||||
})
|
||||
}, file, size, &bd)
|
||||
if err != nil {
|
||||
|
||||
15
pointers.go
15
pointers.go
@@ -1,7 +1,6 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -56,13 +55,13 @@ func ProfilePointerFromTag(refTag Tag) (ProfilePointer, error) {
|
||||
// MatchesEvent checks if the pointer matches an event.
|
||||
func (ep ProfilePointer) MatchesEvent(_ Event) bool { return false }
|
||||
func (ep ProfilePointer) AsFilter() Filter { return Filter{Authors: []PubKey{ep.PublicKey}} }
|
||||
func (ep ProfilePointer) AsTagReference() string { return hex.EncodeToString(ep.PublicKey[:]) }
|
||||
func (ep ProfilePointer) AsTagReference() string { return HexEncodeToString(ep.PublicKey[:]) }
|
||||
|
||||
func (ep ProfilePointer) AsTag() Tag {
|
||||
if len(ep.Relays) > 0 {
|
||||
return Tag{"p", hex.EncodeToString(ep.PublicKey[:]), ep.Relays[0]}
|
||||
return Tag{"p", HexEncodeToString(ep.PublicKey[:]), ep.Relays[0]}
|
||||
}
|
||||
return Tag{"p", hex.EncodeToString(ep.PublicKey[:])}
|
||||
return Tag{"p", HexEncodeToString(ep.PublicKey[:])}
|
||||
}
|
||||
|
||||
// EventPointer represents a pointer to a nostr event.
|
||||
@@ -98,18 +97,18 @@ func EventPointerFromTag(refTag Tag) (EventPointer, error) {
|
||||
|
||||
func (ep EventPointer) MatchesEvent(evt Event) bool { return evt.ID == ep.ID }
|
||||
func (ep EventPointer) AsFilter() Filter { return Filter{IDs: []ID{ep.ID}} }
|
||||
func (ep EventPointer) AsTagReference() string { return hex.EncodeToString(ep.ID[:]) }
|
||||
func (ep EventPointer) AsTagReference() string { return HexEncodeToString(ep.ID[:]) }
|
||||
|
||||
// AsTag converts the pointer to a Tag.
|
||||
func (ep EventPointer) AsTag() Tag {
|
||||
if len(ep.Relays) > 0 {
|
||||
if ep.Author != [32]byte{} {
|
||||
return Tag{"e", hex.EncodeToString(ep.ID[:]), ep.Relays[0], hex.EncodeToString(ep.Author[:])}
|
||||
return Tag{"e", HexEncodeToString(ep.ID[:]), ep.Relays[0], HexEncodeToString(ep.Author[:])}
|
||||
} else {
|
||||
return Tag{"e", hex.EncodeToString(ep.ID[:]), ep.Relays[0]}
|
||||
return Tag{"e", HexEncodeToString(ep.ID[:]), ep.Relays[0]}
|
||||
}
|
||||
}
|
||||
return Tag{"e", hex.EncodeToString(ep.ID[:])}
|
||||
return Tag{"e", HexEncodeToString(ep.ID[:])}
|
||||
}
|
||||
|
||||
// EntityPointer represents a pointer to a nostr entity (addressable event).
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
jwriter "github.com/mailru/easyjson/jwriter"
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
func easyjson33014d6eDecodeFiatjafComNostr(in *jlexer.Lexer, out *ProfilePointer) {
|
||||
@@ -30,7 +29,7 @@ func easyjson33014d6eDecodeFiatjafComNostr(in *jlexer.Lexer, out *ProfilePointer
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
} else {
|
||||
hex.Decode(out.PublicKey[:], in.UnsafeBytes())
|
||||
xhex.Decode(out.PublicKey[:], in.UnsafeBytes())
|
||||
}
|
||||
case "relays":
|
||||
if in.IsNull() {
|
||||
@@ -137,7 +136,7 @@ func easyjson33014d6eDecodeFiatjafComNostr1(in *jlexer.Lexer, out *EventPointer)
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
} else {
|
||||
hex.Decode(out.ID[:], in.UnsafeBytes())
|
||||
xhex.Decode(out.ID[:], in.UnsafeBytes())
|
||||
}
|
||||
case "relays":
|
||||
if in.IsNull() {
|
||||
@@ -164,7 +163,7 @@ func easyjson33014d6eDecodeFiatjafComNostr1(in *jlexer.Lexer, out *EventPointer)
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
} else {
|
||||
hex.Decode(out.Author[:], in.UnsafeBytes())
|
||||
xhex.Decode(out.Author[:], in.UnsafeBytes())
|
||||
}
|
||||
case "kind":
|
||||
out.Kind = Kind(in.Uint16())
|
||||
@@ -262,7 +261,7 @@ func easyjson33014d6eDecodeFiatjafComNostr2(in *jlexer.Lexer, out *EntityPointer
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
} else {
|
||||
hex.Decode(out.PublicKey[:], in.UnsafeBytes())
|
||||
xhex.Decode(out.PublicKey[:], in.UnsafeBytes())
|
||||
}
|
||||
case "kind":
|
||||
out.Kind = Kind(in.Uint16())
|
||||
|
||||
@@ -2,7 +2,6 @@ package schema
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"slices"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/segmentio/encoding/json"
|
||||
"github.com/templexxx/xhex"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -186,7 +186,7 @@ func (v *Validator) validateNext(tag nostr.Tag, index int, this *nextSpec) (fail
|
||||
if len(tag[index]) != 40 {
|
||||
return index, fmt.Errorf("invalid gitcommit at tag '%s', index %d", tag[0], index)
|
||||
}
|
||||
if _, err := hex.Decode(gitcommitdummydecoder, unsafe.Slice(unsafe.StringData(tag[index]), 40)); err != nil {
|
||||
if err := xhex.Decode(gitcommitdummydecoder, unsafe.Slice(unsafe.StringData(tag[index]), 40)); err != nil {
|
||||
return index, fmt.Errorf("invalid gitcommit at tag '%s', index %d", tag[0], index)
|
||||
}
|
||||
case "free":
|
||||
|
||||
@@ -2,7 +2,6 @@ package sdk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -57,7 +56,7 @@ func (sys *System) PrepareNoteEvent(ctx context.Context, evt *nostr.Event) (targ
|
||||
case nostr.ProfilePointer:
|
||||
pk = b.PublicKey
|
||||
// add p tag if not already present
|
||||
if tag := evt.Tags.FindWithValue("p", hex.EncodeToString(b.PublicKey[:])); tag == nil {
|
||||
if tag := evt.Tags.FindWithValue("p", nostr.HexEncodeToString(b.PublicKey[:])); tag == nil {
|
||||
evt.Tags = append(evt.Tags, b.AsTag())
|
||||
}
|
||||
case nostr.EventPointer:
|
||||
@@ -77,7 +76,7 @@ func (sys *System) PrepareNoteEvent(ctx context.Context, evt *nostr.Event) (targ
|
||||
}
|
||||
|
||||
// add e tag if not already present
|
||||
if tag := evt.Tags.FindWithValue("q", hex.EncodeToString(b.ID[:])); tag != nil {
|
||||
if tag := evt.Tags.FindWithValue("q", nostr.HexEncodeToString(b.ID[:])); tag != nil {
|
||||
if len(tag) == 2 {
|
||||
tag = append(tag, relay) // shove this relay hint here
|
||||
}
|
||||
|
||||
15
types.go
15
types.go
@@ -1,10 +1,11 @@
|
||||
package nostr
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
stdjson "encoding/json"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
// RelayEvent represents an event received from a specific relay.
|
||||
@@ -24,11 +25,11 @@ var (
|
||||
)
|
||||
|
||||
func (id ID) String() string { return "id::" + id.Hex() }
|
||||
func (id ID) Hex() string { return hex.EncodeToString(id[:]) }
|
||||
func (id ID) Hex() string { return HexEncodeToString(id[:]) }
|
||||
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
res := make([]byte, 66)
|
||||
hex.Encode(res[1:], id[:])
|
||||
xhex.Encode(res[1:], id[:])
|
||||
res[0] = '"'
|
||||
res[65] = '"'
|
||||
return res, nil
|
||||
@@ -36,9 +37,9 @@ func (id ID) MarshalJSON() ([]byte, error) {
|
||||
|
||||
func (id *ID) UnmarshalJSON(buf []byte) error {
|
||||
if len(buf) != 66 {
|
||||
return fmt.Errorf("must be a hex string of 64 characters")
|
||||
return fmt.Errorf("must be a quoted hex string of 64 characters")
|
||||
}
|
||||
_, err := hex.Decode(id[:], buf[1:65])
|
||||
err := xhex.Decode(id[:], buf[1:65])
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ func IDFromHex(idh string) (ID, error) {
|
||||
if len(idh) != 64 {
|
||||
return id, fmt.Errorf("pubkey should be 64-char hex, got '%s'", idh)
|
||||
}
|
||||
if _, err := hex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
if err := xhex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
return id, fmt.Errorf("'%s' is not valid hex: %w", idh, err)
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ func IDFromHex(idh string) (ID, error) {
|
||||
|
||||
func MustIDFromHex(idh string) ID {
|
||||
id := ID{}
|
||||
if _, err := hex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
if err := xhex.Decode(id[:], unsafe.Slice(unsafe.StringData(idh), 64)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/templexxx/cpu"
|
||||
)
|
||||
|
||||
func TestIDJSONEncoding(t *testing.T) {
|
||||
@@ -25,8 +26,10 @@ func TestIDJSONEncoding(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
|
||||
// test unmarshaling invalid hex
|
||||
err = json.Unmarshal([]byte(`"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"`), &id2)
|
||||
require.Error(t, err)
|
||||
if !cpu.X86.HasAVX2 {
|
||||
err = json.Unmarshal([]byte(`"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"`), &id2)
|
||||
require.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPubKeyJSONEncoding(t *testing.T) {
|
||||
|
||||
27
utils.go
27
utils.go
@@ -3,9 +3,11 @@ package nostr
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"encoding/hex"
|
||||
"net/url"
|
||||
"slices"
|
||||
"unsafe"
|
||||
|
||||
"github.com/templexxx/xhex"
|
||||
)
|
||||
|
||||
// IsValidRelayURL checks if a URL is a valid relay URL (ws:// or wss://).
|
||||
@@ -20,6 +22,27 @@ func IsValidRelayURL(u string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// HexEncodeToString encodes src into a hex string.
|
||||
func HexEncodeToString(src []byte) string {
|
||||
dst := make([]byte, len(src)*2)
|
||||
xhex.Encode(dst, src)
|
||||
return unsafe.String(unsafe.SliceData(dst), len(dst))
|
||||
}
|
||||
|
||||
// HexDecodeString decodes a hex string into bytes.
|
||||
func HexDecodeString(s string) ([]byte, error) {
|
||||
src := unsafe.Slice(unsafe.StringData(s), len(s))
|
||||
if len(src)%2 != 0 {
|
||||
return nil, xhex.ErrLength
|
||||
}
|
||||
dst := make([]byte, len(src)/2)
|
||||
err := xhex.Decode(dst, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// IsValid32ByteHex checks if a string is a valid 32-byte hex string.
|
||||
func IsValid32ByteHex(thing string) bool {
|
||||
if !isLowerHex(thing) {
|
||||
@@ -28,7 +51,7 @@ func IsValid32ByteHex(thing string) bool {
|
||||
if len(thing) != 64 {
|
||||
return false
|
||||
}
|
||||
_, err := hex.DecodeString(thing)
|
||||
_, err := HexDecodeString(thing)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user