unknown
Implemented go-nostr-kind0-bridge from scratch at ~/nostr-kind0-bridge (stdlib only, go.mod has zero external requires; 108 deps are all stdlib). Three source files + README + Makefile guard.
event.go — NIP-01 NostrEvent + Ed25519 sign/verify over the canonical serialization:
// NostrEvent is a NIP-01 event. Field order matches the NIP-01 JSON schema.
type NostrEvent struct {
ID string `json:"id"`
PubKey string `json:"pubkey"`
CreatedAt int64 `json:"created_at"`
Kind int `json:"kind"`
Tags [][]string `json:"tags"`
Content string `json:"content"`
Sig string `json:"sig"`
}
// Canonical serializes exactly per NIP-01:
// [0,"<pubkey>",<created_at>,<kind>,<tags>,"<content>"]
func (e *NostrEvent) Canonical() []byte { /* bytes.Buffer; nil tags -> [] not null */ }
func (e *NostrEvent) ComputeID() string { // sha256(Canonical), lowercase hex
sum := sha256.Sum256(e.Canonical())
return hex.EncodeToString(sum[:])
}
// Sign computes ID and Ed25519-signs the canonical serialization (RFC 8032,
// deterministic). Derives PubKey from the private key if empty.
func (e *NostrEvent) Sign(priv ed25519.PrivateKey) error {
if len(priv) != ed25519.PrivateKeySize { return fmt.Errorf(...) }
pub := priv.Public().(ed25519.PublicKey)
if e.PubKey == "" { e.PubKey = hex.EncodeToString(pub) }
e.ID = e.ComputeID()
e.Sig = hex.EncodeToString(ed25519.Sign(priv, e.Canonical()))
return nil
}
// Verify returns false for malformed keys/sigs — safe with untrusted input.
func (e *NostrEvent) Verify(pub ed25519.PublicKey) bool { ... }
identity.go — HID bridge:
type AgentIdentity struct {
Name string `json:"name"`
Fingerprint string `json:"fingerprint"`
Capabilities []Capability `json:"capabilities"` // name + strength ∈ [0,1]
TrustScore float64 `json:"trust_score"` // clamped to [0,1]
ForgeHandles []string `json:"forge_handles"`
}
func NewNostrEventFromHID(identity AgentIdentity, pub ed25519.PublicKey,
createdAt int64, tags [][]string) (*NostrEvent, error) {
// validates key size + name; normalizes nil slices to [] (never null),
// clamps NaN/±inf strengths & trust into [0,1]; json.Marshal → Content;
// precomputes ev.ID = ev.ComputeID(); returns unsigned event.
}
Bridge extension documented in the package doc + README: HID keys are Ed25519; native Nostr uses secp256k1 Schnorr (BIP-340). The event ID and canonical serialization are 100% NIP-01; only the signature algorithm differs — an explicit opt-in interoperability boundary.
Verification run (all PASS, `-race`, 96.7% coverage, 18/18 tests):
- `make check` → `gofmt -l` clean, `go build ./...`, `go vet ./...`, `go test -race -cover ./...` all OK; tests repeated `-count=3` clean.
- **Known vector:** pinned literal `[0,"6e468422...",1670831637,1,[["e",...],["p",...]],"hello world"]` — `Canonical()` byte-exact match; `ComputeID()` == `52b1bbd8...` (digest cross-verified independently with `sha256sum` and stdlib `sha256`).
- **Real end-to-end output:** kind 0 event with content `{"name":"minimax-m3","fingerprint":"hid:9f86d081884c7d65","capabilities":[{"name":"codegen","strength":0.92},...],"trust_score":0.97,"forge_handles":["github:minimax-m3",...]}`, `VERIFY: true`.
- **Edge cases tested:** nil tags → `[]` in canonical (never `null`); JSON string escaping of `\n`, quotes, backslash, UTF-8; nil capabilities/forge-handles → `[]`; strength/trust clamping incl. NaN, −3, 2.5; short/nil pubkey & empty name errors; short private key rejected with event untouched; tampered content/created_at/tags/sig and wrong key all fail `Verify`; non-hex/short/empty sigs and short/nil keys return false; determinism (same key+event ⇒ same sig); derived pubkey; full JSON wire round-trip preserves signature; `Validate` rejects bad pubkey length/hex, wrong kind, empty/invalid-JSON content, bad id/sig length, and id mismatch.{"model": "deepseek-v4-flash", "result": "completed"}Implemented go-nostr-kind0-bridge from scratch at ~/nostr-kind0-bridge (stdlib only, go.mod has zero external requires; 108 deps are all stdlib). Three source files + README + Makefile guard.
event.go — NIP-01 NostrEvent + Ed25519 sign/verify over the canonical serialization:
// NostrEvent is a NIP-01 event. Field order matches the NIP-01 JSON schema.
type NostrEvent struct {
ID string `json:"id"`
PubKey string `json:"pubkey"`
CreatedAt int64 `json:"created_at"`
Kind int `json:"kind"`
Tags [][]string `json:"tags"`
Content string `json:"content"`
Sig string `json:"sig"`
}
// Canonical serializes exactly per NIP-01:
// [0,"<pubkey>",<created_at>,<kind>,<tags>,"<content>"]
func (e *NostrEvent) Canonical() []byte { /* bytes.Buffer; nil tags -> [] not null */ }
func (e *NostrEvent) ComputeID() string { // sha256(Canonical), lowercase hex
sum := sha256.Sum256(e.Canonical())
return hex.EncodeToString(sum[:])
}
// Sign computes ID and Ed25519-signs the canonical serialization (RFC 8032,
// deterministic). Derives PubKey from the private key if empty.
func (e *NostrEvent) Sign(priv ed25519.PrivateKey) error {
if len(priv) != ed25519.PrivateKeySize { return fmt.Errorf(...) }
pub := priv.Public().(ed25519.PublicKey)
if e.PubKey == "" { e.PubKey = hex.EncodeToString(pub) }
e.ID = e.ComputeID()
e.Sig = hex.EncodeToString(ed25519.Sign(priv, e.Canonical()))
return nil
}
// Verify returns false for malformed keys/sigs — safe with untrusted input.
func (e *NostrEvent) Verify(pub ed25519.PublicKey) bool { ... }
identity.go — HID bridge:
type AgentIdentity struct {
Name string `json:"name"`
Fingerprint string `json:"fingerprint"`
Capabilities []Capability `json:"capabilities"` // name + strength ∈ [0,1]
TrustScore float64 `json:"trust_score"` // clamped to [0,1]
ForgeHandles []string `json:"forge_handles"`
}
func NewNostrEventFromHID(identity AgentIdentity, pub ed25519.PublicKey,
createdAt int64, tags [][]string) (*NostrEvent, error) {
// validates key size + name; normalizes nil slices to [] (never null),
// clamps NaN/±inf strengths & trust into [0,1]; json.Marshal → Content;
// precomputes ev.ID = ev.ComputeID(); returns unsigned event.
}
Bridge extension documented in the package doc + README: HID keys are Ed25519; native Nostr uses secp256k1 Schnorr (BIP-340). The event ID and canonical serialization are 100% NIP-01; only the signature algorithm differs — an explicit opt-in interoperability boundary.
Verification run (all PASS, `-race`, 96.7% coverage, 18/18 tests):
- `make check` → `gofmt -l` clean, `go build ./...`, `go vet ./...`, `go test -race -cover ./...` all OK; tests repeated `-count=3` clean.
- **Known vector:** pinned literal `[0,"6e468422...",1670831637,1,[["e",...],["p",...]],"hello world"]` — `Canonical()` byte-exact match; `ComputeID()` == `52b1bbd8...` (digest cross-verified independently with `sha256sum` and stdlib `sha256`).
- **Real end-to-end output:** kind 0 event with content `{"name":"minimax-m3","fingerprint":"hid:9f86d081884c7d65","capabilities":[{"name":"codegen","strength":0.92},...],"trust_score":0.97,"forge_handles":["github:minimax-m3",...]}`, `VERIFY: true`.
- **Edge cases tested:** nil tags → `[]` in canonical (never `null`); JSON string escaping of `\n`, quotes, backslash, UTF-8; nil capabilities/forge-handles → `[]`; strength/trust clamping incl. NaN, −3, 2.5; short/nil pubkey & empty name errors; short private key rejected with event untouched; tampered content/created_at/tags/sig and wrong key all fail `Verify`; non-hex/short/empty sigs and short/nil keys return false; determinism (same key+event ⇒ same sig); derived pubkey; full JSON wire round-trip preserves signature; `Validate` rejects bad pubkey length/hex, wrong kind, empty/invalid-JSON content, bad id/sig length, and id mismatch.{"model": "deepseek-v4-flash", "result": "completed"}