- Replaced all instances of p256k1signer with the new p8k.Signer across various modules, including event creation, policy handling, and database interactions. - Updated related test cases and benchmarks to ensure compatibility with the new signer interface. - Bumped version to v0.25.0 to reflect these significant changes and improvements in cryptographic operations.
189 lines
4.1 KiB
Go
189 lines
4.1 KiB
Go
package nwc_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"next.orly.dev/pkg/crypto/encryption"
|
|
"next.orly.dev/pkg/encoders/event"
|
|
"next.orly.dev/pkg/encoders/hex"
|
|
"next.orly.dev/pkg/encoders/tag"
|
|
"next.orly.dev/pkg/interfaces/signer/p8k"
|
|
"next.orly.dev/pkg/protocol/nwc"
|
|
"next.orly.dev/pkg/utils"
|
|
)
|
|
|
|
func TestNWCConversationKey(t *testing.T) {
|
|
secret := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
walletPubkey := "816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b"
|
|
|
|
uri := "nostr+walletconnect://" + walletPubkey + "?relay=wss://relay.getalby.com/v1&secret=" + secret
|
|
|
|
parts, err := nwc.ParseConnectionURI(uri)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Validate conversation key was generated
|
|
convKey := parts.GetConversationKey()
|
|
if len(convKey) == 0 {
|
|
t.Fatal("conversation key should not be empty")
|
|
}
|
|
|
|
// Validate wallet public key
|
|
walletKey := parts.GetWalletPublicKey()
|
|
if len(walletKey) == 0 {
|
|
t.Fatal("wallet public key should not be empty")
|
|
}
|
|
|
|
expected, err := hex.Dec(walletPubkey)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(walletKey) != len(expected) {
|
|
t.Fatal("wallet public key length mismatch")
|
|
}
|
|
|
|
for i := range walletKey {
|
|
if walletKey[i] != expected[i] {
|
|
t.Fatal("wallet public key mismatch")
|
|
}
|
|
}
|
|
|
|
// Test passed
|
|
}
|
|
|
|
func TestNWCEncryptionDecryption(t *testing.T) {
|
|
secret := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
walletPubkey := "816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b"
|
|
|
|
uri := "nostr+walletconnect://" + walletPubkey + "?relay=wss://relay.getalby.com/v1&secret=" + secret
|
|
|
|
parts, err := nwc.ParseConnectionURI(uri)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
convKey := parts.GetConversationKey()
|
|
testMessage := `{"method":"get_info","params":null}`
|
|
|
|
// Test encryption
|
|
encrypted, err := encryption.Encrypt([]byte(testMessage), convKey)
|
|
if err != nil {
|
|
t.Fatalf("encryption failed: %v", err)
|
|
}
|
|
|
|
if len(encrypted) == 0 {
|
|
t.Fatal("encrypted message should not be empty")
|
|
}
|
|
|
|
// Test decryption
|
|
decrypted, err := encryption.Decrypt(encrypted, convKey)
|
|
if err != nil {
|
|
t.Fatalf("decryption failed: %v", err)
|
|
}
|
|
|
|
if string(decrypted) != testMessage {
|
|
t.Fatalf(
|
|
"decrypted message mismatch: got %s, want %s", string(decrypted),
|
|
testMessage,
|
|
)
|
|
}
|
|
|
|
// Test passed
|
|
}
|
|
|
|
func TestNWCEventCreation(t *testing.T) {
|
|
secretBytes, err := hex.Dec("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
clientKey := p8k.MustNew()
|
|
if err := clientKey.InitSec(secretBytes); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
walletPubkey, err := hex.Dec("816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
convKey, err := encryption.GenerateConversationKeyWithSigner(
|
|
clientKey, walletPubkey,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
request := map[string]any{"method": "get_info"}
|
|
reqBytes, err := json.Marshal(request)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
encrypted, err := encryption.Encrypt(reqBytes, convKey)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create NWC event
|
|
ev := &event.E{
|
|
Content: encrypted,
|
|
CreatedAt: time.Now().Unix(),
|
|
Kind: 23194,
|
|
Tags: tag.NewS(
|
|
tag.NewFromAny("encryption", "nip44_v2"),
|
|
tag.NewFromAny("p", hex.Enc(walletPubkey)),
|
|
),
|
|
}
|
|
|
|
if err := ev.Sign(clientKey); err != nil {
|
|
t.Fatalf("event signing failed: %v", err)
|
|
}
|
|
|
|
// Validate event structure
|
|
if len(ev.Content) == 0 {
|
|
t.Fatal("event content should not be empty")
|
|
}
|
|
|
|
if len(ev.ID) == 0 {
|
|
t.Fatal("event should have ID after signing")
|
|
}
|
|
|
|
if len(ev.Sig) == 0 {
|
|
t.Fatal("event should have signature after signing")
|
|
}
|
|
|
|
// Validate tags
|
|
hasEncryption := false
|
|
hasP := false
|
|
for i := 0; i < ev.Tags.Len(); i++ {
|
|
tag := ev.Tags.GetTagElement(i)
|
|
if tag.Len() >= 2 {
|
|
if utils.FastEqual(
|
|
tag.T[0], "encryption",
|
|
) && utils.FastEqual(tag.T[1], "nip44_v2") {
|
|
hasEncryption = true
|
|
}
|
|
if utils.FastEqual(
|
|
tag.T[0], "p",
|
|
) && utils.FastEqual(tag.T[1], hex.Enc(walletPubkey)) {
|
|
hasP = true
|
|
}
|
|
}
|
|
}
|
|
|
|
if !hasEncryption {
|
|
t.Fatal("event missing encryption tag")
|
|
}
|
|
|
|
if !hasP {
|
|
t.Fatal("event missing p tag")
|
|
}
|
|
|
|
// Test passed
|
|
}
|