2024-01-01 13:07:25 -03:00
2023-09-07 07:05:01 -03:00
2023-06-12 08:18:29 -03:00
2023-05-31 12:35:48 -03:00
2023-11-20 14:59:12 -03:00
2023-09-07 07:05:01 -03:00
2023-09-07 07:05:01 -03:00
wip
2024-01-01 13:07:25 -03:00
2023-09-07 07:05:01 -03:00
2023-09-07 07:05:01 -03:00
2023-10-02 12:26:34 -03:00
2023-09-07 07:05:01 -03:00
wip
2024-01-01 13:07:25 -03:00
2023-11-06 18:50:55 -03:00
2023-11-28 15:14:35 -03:00
2023-12-29 18:16:58 -03:00
2023-12-29 18:16:58 -03:00
2024-01-01 10:15:06 -03:00
2022-10-07 16:52:01 -07:00
2023-07-11 15:25:02 -03:00
2023-11-28 22:23:51 -03:00
2023-05-04 08:24:26 -03:00
2023-12-15 14:15:37 -03:00
2023-12-09 14:40:39 -03:00
2023-12-09 13:21:35 -03:00
2022-11-11 10:52:23 -03:00
2023-12-29 18:10:56 -03:00
2023-11-28 22:24:05 -03:00

Run Tests Go Reference Go Report Card

go-nostr

A set of useful things for Nostr Protocol implementations.

go get github.com/nbd-wtf/go-nostr

Generating a key

package main

import (
    "fmt"

    "github.com/nbd-wtf/go-nostr"
    "github.com/nbd-wtf/go-nostr/nip19"
)

func main() {
    sk := nostr.GeneratePrivateKey()
    pk, _ := nostr.GetPublicKey(sk)
    nsec, _ := nip19.EncodePrivateKey(sk)
    npub, _ := nip19.EncodePublicKey(pk)

    fmt.Println("sk:", sk)
    fmt.Println("pk:", pk)
    fmt.Println(nsec)
    fmt.Println(npub)
}

Subscribing to a single relay

ctx := context.Background()
relay, err := nostr.RelayConnect(ctx, "wss://nostr.zebedee.cloud")
if err != nil {
	panic(err)
}

npub := "npub1422a7ws4yul24p0pf7cacn7cghqkutdnm35z075vy68ggqpqjcyswn8ekc"

var filters nostr.Filters
if _, v, err := nip19.Decode(npub); err == nil {
	pub := v.(string)
	filters = []nostr.Filter{{
		Kinds:   []int{nostr.KindTextNote},
		Authors: []string{pub},
		Limit:   1,
	}}
} else {
	panic(err)
}

ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()

sub, err := relay.Subscribe(ctx, filters)
if err != nil {
	panic(err)
}

for ev := range sub.Events {
	// handle returned event.
	// channel will stay open until the ctx is cancelled (in this case, context timeout)
	fmt.Println(ev.ID)
}

Publishing to two relays

sk := nostr.GeneratePrivateKey()
pub, _ := nostr.GetPublicKey(sk)

ev := nostr.Event{
	PubKey:    pub,
	CreatedAt: nostr.Now(),
	Kind:      nostr.KindTextNote,
	Tags:      nil,
	Content:   "Hello World!",
}

// calling Sign sets the event ID field and the event Sig field
ev.Sign(sk)

// publish the event to two relays
ctx := context.Background()
for _, url := range []string{"wss://nostr.zebedee.cloud", "wss://nostr-pub.wellorder.net"} {
	relay, err := nostr.RelayConnect(ctx, url)
	if err != nil {
		fmt.Println(err)
		continue
	}
	if err := relay.Publish(ctx, ev); err != nil {
		fmt.Println(err)
		continue
	}

	fmt.Printf("published to %s\n", url)
}

Example script

go run example/example.go

Warning: risk of goroutine bloat (if used incorrectly)

Remember to cancel subscriptions, either by calling .Unsub() on them or ensuring their context.Context will be canceled at some point. If you don't do that they will keep creating a new goroutine for every new event that arrives and if you have stopped listening on the sub.Events channel that will cause chaos and doom in your program.

Description
Nostr library for Golang
Readme 5.5 MiB
Languages
C 83.7%
Go 15.5%
Assembly 0.7%
Just 0.1%