2022-10-07 18:51:36 -07:00
< a href = "https://nbd.wtf" > < img align = "right" height = "196" src = "https://user-images.githubusercontent.com/1653275/194609043-0add674b-dd40-41ed-986c-ab4a2e053092.png" / > < / a >
2021-12-16 20:47:53 -03:00
go-nostr
========
2022-11-04 08:24:32 -03:00
A set of useful things for [Nostr Protocol ](https://github.com/nostr-protocol/nostr ) implementations.
2021-12-16 20:47:53 -03:00
2022-11-04 08:24:32 -03:00
< a href = "https://godoc.org/github.com/nbd-wtf/go-nostr" > < img src = "https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt = "GoDoc" > < / a >
2023-02-14 17:50:33 +01:00
< br / >
[](https://github.com/nbd-wtf/go-nostr/actions/workflows/test.yml)
2021-12-16 20:47:53 -03:00
2023-02-03 22:36:21 +08:00
Install go-nostr:
```bash
go get github.com/nbd-wtf/go-nostr
```
2022-01-05 10:16:36 -04:00
### Generating a key
``` go
2023-02-03 22:36:21 +08:00
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)
}
2022-01-05 10:16:36 -04:00
```
2023-01-13 18:50:35 -05:00
2023-01-13 22:07:08 -05:00
### Subscribing to a single relay
``` go
2023-05-07 14:28:54 +09:00
ctx := context.Background()
relay, err := nostr.RelayConnect(ctx, "wss://nostr.zebedee.cloud")
2023-01-13 22:07:08 -05:00
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{{
2023-05-07 14:28:54 +09:00
Kinds: []int{nostr.KindTextNote},
2023-01-13 22:07:08 -05:00
Authors: []string{pub},
Limit: 1,
}}
} else {
panic(err)
}
2023-05-07 14:28:54 +09:00
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
2023-01-13 22:07:08 -05:00
2023-05-07 14:28:54 +09:00
sub, err := relay.Subscribe(ctx, filters)
if err != nil {
panic(err)
}
2023-01-13 22:07:08 -05:00
for ev := range sub.Events {
// handle returned event.
2023-05-07 14:28:54 +09:00
// channel will stay open until the ctx is cancelled (in this case, context timeout)
2023-01-15 07:19:00 -05:00
fmt.Println(ev.ID)
2023-01-13 22:07:08 -05:00
}
```
2023-01-13 22:08:27 -05:00
### Publishing to two relays
2023-01-13 22:07:08 -05:00
``` go
sk := nostr.GeneratePrivateKey()
pub, _ := nostr.GetPublicKey(sk)
ev := nostr.Event{
PubKey: pub,
2023-04-16 16:25:25 -03:00
CreatedAt: nostr.Now(),
2023-05-07 14:28:54 +09:00
Kind: nostr.KindTextNote,
2023-01-13 22:07:08 -05:00
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
2023-05-07 14:28:54 +09:00
ctx := context.Background()
2023-01-13 22:07:08 -05:00
for _, url := range []string{"wss://nostr.zebedee.cloud", "wss://nostr-pub.wellorder.net"} {
2023-05-07 14:28:54 +09:00
relay, err := nostr.RelayConnect(ctx, url)
if err != nil {
fmt.Println(err)
2023-01-13 22:07:08 -05:00
continue
}
2023-05-07 14:28:54 +09:00
_, err = relay.Publish(ctx, ev)
if err != nil {
fmt.Println(err)
continue
}
fmt.Printf("published to %s\n", url)
2023-01-13 22:07:08 -05:00
}
```
2023-01-16 06:27:11 -05:00
### Authenticating with NIP-42
For this section, the user needs access to a relay implementing NIP-42.
E.g., https://github.com/fiatjaf/relayer with a relay implementing the relayer.Auther interface.
``` go
func main() {
url := "ws://localhost:7447"
2023-06-25 18:01:25 -03:00
sk := nostr.GeneratePrivateKey()
relay, err := nostr.RelayConnect(context.Background(), url,
nostr.WithAuthHandler(func(ctx context.Context, authEvent *Event) (ok bool) {
authEvent.Sign(sk)
}),
)
2023-01-16 06:27:11 -05:00
if err != nil {
panic(err)
}
}
```
2023-01-13 22:07:08 -05:00
### Example script
2023-01-13 18:50:35 -05:00
```
go run example/example.go
```