NAME
Net::Nostr::Key - Secp256k1 keypair management for Nostr
SYNOPSIS
use Net::Nostr::Key;
# Generate a new keypair
my $key = Net::Nostr::Key->new;
say $key->pubkey_npub; # npub1...
say $key->privkey_nsec; # nsec1...
say $key->pubkey_hex; # 64-char hex (x-only, BIP-340)
say $key->privkey_hex; # 64-char hex
# Save and load from file
$key->save_privkey('my_key.pem');
my $key = Net::Nostr::Key->new(privkey => 'my_key.pem');
# Create and sign an event
my $event = $key->create_event(kind => 1, content => 'hello', tags => []);
# Load from DER data
my $key = Net::Nostr::Key->new(privkey => \$der_bytes);
my $key = Net::Nostr::Key->new(pubkey => \$der_bytes);
DESCRIPTION
Manages secp256k1 keypairs for the Nostr protocol. Supports key generation, import/export in multiple formats (hex, raw, DER, PEM, NIP-19 bech32), file-based key storage, and BIP-340 Schnorr signatures.
CONSTRUCTOR
new
my $key = Net::Nostr::Key->new;
my $key = Net::Nostr::Key->new(privkey => \$der_bytes);
my $key = Net::Nostr::Key->new(pubkey => \$der_bytes);
my $key = Net::Nostr::Key->new(privkey => 'my_key.pem');
Without arguments, generates a new secp256k1 keypair. Pass privkey or pubkey as a scalar reference to key data (DER or PEM), or as a filename string to load from a file (PEM or DER format). When only a public key is loaded, signing operations will fail.
# Save a key to a file and load it back
$key->save_privkey('my_key.pem');
my $key = Net::Nostr::Key->new(privkey => 'my_key.pem');
METHODS
schnorr_sign
my $sig = $key->schnorr_sign($message); # 64 raw bytes
Signs the given message using BIP-340 Schnorr signatures. Returns the raw 64-byte signature. Requires a private key to be loaded.
my $key = Net::Nostr::Key->new;
my $sig = $key->schnorr_sign('hello');
say length($sig); # 64
privkey_loaded
my $bool = $key->privkey_loaded;
Returns true if a private key is loaded (i.e. signing is possible).
pubkey_loaded
my $bool = $key->pubkey_loaded;
Returns true if any key material is loaded (public or private).
my $key = Net::Nostr::Key->new(pubkey => \$der);
say $key->pubkey_loaded; # 1
say $key->privkey_loaded; # 0
pubkey_hex
my $hex = $key->pubkey_hex; # 64-char lowercase hex
Returns the x-only public key as a 64-character hex string, suitable for use as a Nostr pubkey (BIP-340 format).
privkey_hex
my $hex = $key->privkey_hex; # 64-char lowercase hex
Returns the private key as a 64-character hex string.
pubkey_npub
my $npub = $key->pubkey_npub; # 'npub1...'
Returns the public key as a NIP-19 bech32-encoded npub string.
my $key = Net::Nostr::Key->new;
say $key->pubkey_npub; # npub1...
privkey_nsec
my $nsec = $key->privkey_nsec; # 'nsec1...'
Returns the private key as a NIP-19 bech32-encoded nsec string.
my $key = Net::Nostr::Key->new;
say $key->privkey_nsec; # nsec1...
pubkey_raw
my $raw = $key->pubkey_raw; # 65 bytes (04 || x || y)
Returns the uncompressed public key as raw bytes (65 bytes with 04 prefix).
privkey_raw
my $raw = $key->privkey_raw; # 32 bytes
Returns the private key as 32 raw bytes.
pubkey_der
my $der = $key->pubkey_der;
Returns the public key in DER-encoded format. Can be passed to a new Key constructor:
my $key2 = Net::Nostr::Key->new(pubkey => \$key->pubkey_der);
privkey_der
my $der = $key->privkey_der;
Returns the private key in DER-encoded format.
my $key2 = Net::Nostr::Key->new(privkey => \$key->privkey_der);
pubkey_pem
my $pem = $key->pubkey_pem;
Returns the public key in PEM-encoded format (Base64 with header/footer).
say $key->pubkey_pem;
# -----BEGIN PUBLIC KEY-----
# ...
# -----END PUBLIC KEY-----
privkey_pem
my $pem = $key->privkey_pem;
Returns the private key in PEM-encoded format.
save_privkey
$key->save_privkey('my_key.pem');
Saves the private key to the given file path in PEM format. Croaks if no private key is loaded.
my $key = Net::Nostr::Key->new;
$key->save_privkey('my_key.pem');
# Load it back later
my $same_key = Net::Nostr::Key->new(privkey => 'my_key.pem');
save_pubkey
$key->save_pubkey('my_pubkey.pem');
Saves the public key to the given file path in PEM format.
my $key = Net::Nostr::Key->new;
$key->save_pubkey('my_pubkey.pem');
my $pub_only = Net::Nostr::Key->new(pubkey => 'my_pubkey.pem');
sign_event
my $sig_hex = $key->sign_event($event);
Signs the event's ID with BIP-340 Schnorr and sets the event's sig field. Returns the signature as a 128-character hex string.
my $event = Net::Nostr::Event->new(
pubkey => $key->pubkey_hex, kind => 1,
content => 'hello', tags => [],
);
$key->sign_event($event);
say $event->sig; # 128-char hex
create_event
my $event = $key->create_event(kind => 1, content => 'hello', tags => []);
Convenience method that creates a new Net::Nostr::Event with the key's public key, signs it, and returns the signed event.
my $event = $key->create_event(
kind => 1,
content => 'hello world',
tags => [['t', 'nostr']],
);
say $event->id; # set
say $event->sig; # set
constructor_keys
my @keys = Net::Nostr::Key->constructor_keys; # ('privkey', 'pubkey')
Returns the list of valid constructor argument names. Used internally by Net::Nostr to extract key-related arguments.