Nostr Bench32 Encoding in GoNostr uses the Bech32 encoding format. This defines a segwit address format - also known the bc1 address - and defined by BIP 0173 and BIP 0350. The Bech32 address format is now used by many digital wallets. |
Theory
At the core of Bitcoin is the usage of the Bitcoin address, and which defines the sender and recipient of Bitcoin transactions. The newest format is known as SegWit address format — and is specified here: [link], and is defined as the BIP (Bitcoin Improvement Protocol) 173. With Bitcoin, these addresses start with “bc1” and use a Bech32 encoding format.
The Bech32 addresses are human readable. The first part is 1 to 83 US-ASCII characters, with each character in the range of 33 to 126. There is then a “1” as a seperate, and followed by the data part which is alphanumeric characters that exclude “1”, “b”, “i”, and “o”:
000 001 010 011 100 101 110 111 -------------------------------------- 00 | q p z r y 9 x 8 01 | g f 2 t v d w 0 10 | s 3 j n 5 4 k h 11 | c e 6 m u a 7 l
With Nostr, the private key has a prefix of “nsec”, and the public key has the prefix of “npub”. These are defined as “HRP” — the human readable part — elements. After this, there is a seperator of a “1”, and followed by the key data. A sample run is:
Private Nosstr encoded: nsec1zlq53zvdut685jnqf3y63pmwwz73y2afp3heqxxmgwdgc3vt3rrqf2ywkr Public Nosstr encoded: npub1pkgw9u7y0e36y547fadcq6zrz5a72cf8gma26rlsqle0aa6p9jls0ne8nx
The private key is: zlq53zvdut685jnqf3y63pmwwz73y2afp3heqxxmgwdgc3vt3rrqf2ywkr, and in hex will be 17c148898de2f47a4a604c49a8876e70bd122ba90c6f9018db439a8c458b88c6.
Note that the last six six characters of the data part define the checksum.
Coding
The coding is:
package main import ( "fmt" "os" "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" ) func main() { message :="Hello world!" argCount := len(os.Args[1:]) if (argCount>0) {message = string(os.Args[1])} sk := nostr.GeneratePrivateKey() pk, _ := nostr.GetPublicKey(sk) nostr_priv, _ := nip19.EncodePrivateKey(sk) nostr_pub, _ := nip19.EncodePublicKey(pk) relays := []string{"wss://relay.n057r.club","wss://nostr.lu.ke"} nostr_profile, _ := nip19.EncodeProfile(pk,relays) fmt.Printf("Private key {%v}\n",sk) fmt.Printf("Public key: {%v}\n", pk) fmt.Printf("\nPrivate Nosstr encoded: %v\n",nostr_priv) fmt.Printf("Public Nosstr encoded: %v\n",nostr_pub) fmt.Printf("Public Nosstr encoded: %v\n",nostr_profile) ev := nostr.Event{ PubKey: pk, CreatedAt: nostr.Now(), Kind: nostr.KindTextNote, Tags: nil, Content: message, } ev.Sign(sk) fmt.Printf("\nEvent ID: %s\n",ev.ID) fmt.Printf("Event Tags: %v\n",ev.Tags) fmt.Printf("Event Content: %v\n",ev.Content) fmt.Printf("Event Sig: %v\n",ev.Sig) fmt.Printf("Event Kind: %v\n",ev.Kind) fmt.Printf("Event CreatedAt: %v\n",ev.CreatedAt) fmt.Printf("Event Pubkey: %v\n",ev.PubKey) nostr_event, _ := nip19.EncodeNote(ev.ID) fmt.Printf("\nEvent ID %v. Encoded: %v\n",ev.ID,nostr_event) }
and a sample run is:
Private key: 17c148898de2f47a4a604c49a8876e70bd122ba90c6f9018db439a8c458b88c6 Public key: 0d90e2f3c47e63a252be4f5b806843153be5612746faad0ff007f2fef7412cbf Private Nosstr encoded: nsec1zlq53zvdut685jnqf3y63pmwwz73y2afp3heqxxmgwdgc3vt3rrqf2ywkr Public Nosstr encoded: npub1pkgw9u7y0e36y547fadcq6zrz5a72cf8gma26rlsqle0aa6p9jls0ne8nx Profile Nosstr encoded: nprofile1qqsqmy8z70z8ucaz22ly7kuqdpp32wl9vyn5d74dplcq0uh77aqje0cpzemhxue69uhhyetvv9ujum3sx5mhytnrd36kyqg3waehxw309ahx7um5wghxcafwddjsh0y88w Event ID: 99e32c54cd5379b6399c38700875c1ae8f9e85ce34cb1470791b786d051a1455 Event Tags: [] Event Content: Hello. How are you? Event Sig: 7389fd9f89a2bb50ec90b259452a0cc0dbaee22be9cad8140c0a518ed6c0dffe65e4642bdca19657f8215991bb775e48c7aae47cfe748f267e8d38dababb8db4 Event Kind: 1 Event CreatedAt: 1715079273 Event Pubkey: 0d90e2f3c47e63a252be4f5b806843153be5612746faad0ff007f2fef7412cbf Event ID 99e32c54cd5379b6399c38700875c1ae8f9e85ce34cb1470791b786d051a1455. Encoded: note1n83jc4xd2dumvwvu8pcqsawp468eapwwxn93gurerdux6pg6z32srd5wtl