Files
next.orly.dev/cmd/FIND/main.go
mleku bf8d912063
Some checks failed
Go / build (push) Has been cancelled
Go / release (push) Has been cancelled
enhance spider with rate limit handling, follow list updates, and improved reconnect logic; bump version to v0.29.0
also reduces CPU load for spider, and minor CORS fixes
2025-11-14 21:15:24 +00:00

284 lines
7.3 KiB
Go

package main
import (
"fmt"
"os"
"time"
"next.orly.dev/pkg/crypto/keys"
"next.orly.dev/pkg/encoders/hex"
"next.orly.dev/pkg/find"
"next.orly.dev/pkg/interfaces/signer"
"next.orly.dev/pkg/interfaces/signer/p8k"
)
func main() {
if len(os.Args) < 2 {
printUsage()
os.Exit(1)
}
command := os.Args[1]
switch command {
case "register":
handleRegister()
case "transfer":
handleTransfer()
case "verify-name":
handleVerifyName()
case "generate-key":
handleGenerateKey()
case "issue-cert":
handleIssueCert()
case "help":
printUsage()
default:
fmt.Printf("Unknown command: %s\n\n", command)
printUsage()
os.Exit(1)
}
}
func printUsage() {
fmt.Println("FIND - Free Internet Name Daemon")
fmt.Println("Usage: find <command> [options]")
fmt.Println()
fmt.Println("Commands:")
fmt.Println(" register <name> Create a registration proposal for a name")
fmt.Println(" transfer <name> <new-owner> Transfer a name to a new owner")
fmt.Println(" verify-name <name> Validate a name format")
fmt.Println(" generate-key Generate a new key pair")
fmt.Println(" issue-cert <name> Issue a certificate for a name")
fmt.Println(" help Show this help message")
fmt.Println()
fmt.Println("Examples:")
fmt.Println(" find verify-name example.com")
fmt.Println(" find register myname.nostr")
fmt.Println(" find generate-key")
}
func handleRegister() {
if len(os.Args) < 3 {
fmt.Println("Usage: find register <name>")
os.Exit(1)
}
name := os.Args[2]
// Validate the name
if err := find.ValidateName(name); err != nil {
fmt.Printf("Invalid name: %v\n", err)
os.Exit(1)
}
// Generate a key pair for this example
// In production, this would load from a secure keystore
signer, err := p8k.New()
if err != nil {
fmt.Printf("Failed to create signer: %v\n", err)
os.Exit(1)
}
if err := signer.Generate(); err != nil {
fmt.Printf("Failed to generate key: %v\n", err)
os.Exit(1)
}
// Create registration proposal
proposal, err := find.NewRegistrationProposal(name, find.ActionRegister, signer)
if err != nil {
fmt.Printf("Failed to create proposal: %v\n", err)
os.Exit(1)
}
fmt.Printf("Registration Proposal Created\n")
fmt.Printf("==============================\n")
fmt.Printf("Name: %s\n", name)
fmt.Printf("Pubkey: %s\n", hex.Enc(signer.Pub()))
fmt.Printf("Event ID: %s\n", hex.Enc(proposal.GetIDBytes()))
fmt.Printf("Kind: %d\n", proposal.Kind)
fmt.Printf("Created At: %s\n", time.Unix(proposal.CreatedAt, 0))
fmt.Printf("\nEvent JSON:\n")
json := proposal.Marshal(nil)
fmt.Println(string(json))
}
func handleTransfer() {
if len(os.Args) < 4 {
fmt.Println("Usage: find transfer <name> <new-owner-pubkey>")
os.Exit(1)
}
name := os.Args[2]
newOwnerPubkey := os.Args[3]
// Validate the name
if err := find.ValidateName(name); err != nil {
fmt.Printf("Invalid name: %v\n", err)
os.Exit(1)
}
// Generate current owner key (in production, load from keystore)
currentOwner, err := p8k.New()
if err != nil {
fmt.Printf("Failed to create current owner signer: %v\n", err)
os.Exit(1)
}
if err := currentOwner.Generate(); err != nil {
fmt.Printf("Failed to generate current owner key: %v\n", err)
os.Exit(1)
}
// Authorize the transfer
prevSig, timestamp, err := find.AuthorizeTransfer(name, newOwnerPubkey, currentOwner)
if err != nil {
fmt.Printf("Failed to authorize transfer: %v\n", err)
os.Exit(1)
}
fmt.Printf("Transfer Authorization Created\n")
fmt.Printf("===============================\n")
fmt.Printf("Name: %s\n", name)
fmt.Printf("Current Owner: %s\n", hex.Enc(currentOwner.Pub()))
fmt.Printf("New Owner: %s\n", newOwnerPubkey)
fmt.Printf("Timestamp: %s\n", timestamp)
fmt.Printf("Signature: %s\n", prevSig)
fmt.Printf("\nTo complete the transfer, the new owner must create a proposal with:")
fmt.Printf(" prev_owner: %s\n", hex.Enc(currentOwner.Pub()))
fmt.Printf(" prev_sig: %s\n", prevSig)
}
func handleVerifyName() {
if len(os.Args) < 3 {
fmt.Println("Usage: find verify-name <name>")
os.Exit(1)
}
name := os.Args[2]
// Validate the name
if err := find.ValidateName(name); err != nil {
fmt.Printf("❌ Invalid name: %v\n", err)
os.Exit(1)
}
normalized := find.NormalizeName(name)
isTLD := find.IsTLD(normalized)
parent := find.GetParentDomain(normalized)
fmt.Printf("✓ Valid name\n")
fmt.Printf("==============\n")
fmt.Printf("Original: %s\n", name)
fmt.Printf("Normalized: %s\n", normalized)
fmt.Printf("Is TLD: %v\n", isTLD)
if parent != "" {
fmt.Printf("Parent: %s\n", parent)
}
}
func handleGenerateKey() {
// Generate a new key pair
secKey, err := keys.GenerateSecretKey()
if err != nil {
fmt.Printf("Failed to generate secret key: %v\n", err)
os.Exit(1)
}
secKeyHex := hex.Enc(secKey)
pubKeyHex, err := keys.GetPublicKeyHex(secKeyHex)
if err != nil {
fmt.Printf("Failed to derive public key: %v\n", err)
os.Exit(1)
}
fmt.Println("New Key Pair Generated")
fmt.Println("======================")
fmt.Printf("Secret Key (keep safe!): %s\n", secKeyHex)
fmt.Printf("Public Key: %s\n", pubKeyHex)
fmt.Println()
fmt.Println("⚠️ IMPORTANT: Store the secret key securely. Anyone with access to it can control your names.")
}
func handleIssueCert() {
if len(os.Args) < 3 {
fmt.Println("Usage: find issue-cert <name>")
os.Exit(1)
}
name := os.Args[2]
// Validate the name
if err := find.ValidateName(name); err != nil {
fmt.Printf("Invalid name: %v\n", err)
os.Exit(1)
}
// Generate name owner key
owner, err := p8k.New()
if err != nil {
fmt.Printf("Failed to create owner signer: %v\n", err)
os.Exit(1)
}
if err := owner.Generate(); err != nil {
fmt.Printf("Failed to generate owner key: %v\n", err)
os.Exit(1)
}
// Generate certificate key (different from name owner)
certSigner, err := p8k.New()
if err != nil {
fmt.Printf("Failed to create cert signer: %v\n", err)
os.Exit(1)
}
if err := certSigner.Generate(); err != nil {
fmt.Printf("Failed to generate cert key: %v\n", err)
os.Exit(1)
}
certPubkey := hex.Enc(certSigner.Pub())
// Generate 3 witness signers (in production, these would be separate services)
var witnesses []signer.I
for i := 0; i < 3; i++ {
witness, err := p8k.New()
if err != nil {
fmt.Printf("Failed to create witness %d: %v\n", i, err)
os.Exit(1)
}
if err := witness.Generate(); err != nil {
fmt.Printf("Failed to generate witness %d key: %v\n", i, err)
os.Exit(1)
}
witnesses = append(witnesses, witness)
}
// Issue certificate (90 day validity)
cert, err := find.IssueCertificate(name, certPubkey, find.CertificateValidity, owner, witnesses)
if err != nil {
fmt.Printf("Failed to issue certificate: %v\n", err)
os.Exit(1)
}
fmt.Printf("Certificate Issued\n")
fmt.Printf("==================\n")
fmt.Printf("Name: %s\n", cert.Name)
fmt.Printf("Cert Pubkey: %s\n", cert.CertPubkey)
fmt.Printf("Valid From: %s\n", cert.ValidFrom)
fmt.Printf("Valid Until: %s\n", cert.ValidUntil)
fmt.Printf("Challenge: %s\n", cert.Challenge)
fmt.Printf("Witnesses: %d\n", len(cert.Witnesses))
fmt.Printf("Algorithm: %s\n", cert.Algorithm)
fmt.Printf("Usage: %s\n", cert.Usage)
fmt.Printf("\nWitness Pubkeys:\n")
for i, w := range cert.Witnesses {
fmt.Printf(" %d: %s\n", i+1, w.Pubkey)
}
}