What
- New
nipIC package implementing NIP-IC (Identity Connection): NewAttestation/ParseAttestation/ValidateAttestation (Kind 35522), ParseIdentityConnection/ValidateIdentityConnection (Kind 35521), NewChallenge/ChallengeToken.Verify (npv1 cross-IA challenge binding), EncodeNConnection/DecodeNConnection (bech32 profile-link format).
nipAZ now depends on nipIC for WebIdentity/ConnectionKey (re-exported) and gains a new Identity type (Pubkey/Connection/ResolvedConnection/WithHandle) replacing raw string Recipient/Sender/*Provider params — breaking.
- All
nipAZ.New* constructors now sign internally and return (*nip01.Event, error) instead of an unsigned event the caller had to .Sign() separately — breaking.
- Security fix:
NewAltZapReceipt no longer silently re-derives its p/P tags by parsing the embedded request's description JSON — it only ever uses Identity values the caller explicitly passed.
nipIC.NewChallenge's session entropy fixed to 16 bytes (32 hex chars) to match its real caller.
Why
nipAZ's own spec assigns ConnectionKey/WebIdentity ownership to NIP-IC, but there was no NIP-IC implementation to depend on — zapf had a hand-rolled, duplicate copy instead. This extracts it into nmilat as nipIC, the same way NIP-AZ was previously extracted, and closes a receipt-tag spoofing gap found while doing so.
Test plan
What
nipICpackage implementing NIP-IC (Identity Connection):NewAttestation/ParseAttestation/ValidateAttestation(Kind 35522),ParseIdentityConnection/ValidateIdentityConnection(Kind 35521),NewChallenge/ChallengeToken.Verify(npv1 cross-IA challenge binding),EncodeNConnection/DecodeNConnection(bech32 profile-link format).nipAZnow depends onnipICforWebIdentity/ConnectionKey(re-exported) and gains a newIdentitytype (Pubkey/Connection/ResolvedConnection/WithHandle) replacing raw stringRecipient/Sender/*Providerparams — breaking.nipAZ.New*constructors now sign internally and return(*nip01.Event, error)instead of an unsigned event the caller had to.Sign()separately — breaking.NewAltZapReceiptno longer silently re-derives itsp/Ptags by parsing the embedded request'sdescriptionJSON — it only ever usesIdentityvalues the caller explicitly passed.nipIC.NewChallenge's session entropy fixed to 16 bytes (32 hex chars) to match its real caller.Why
nipAZ's own spec assigns ConnectionKey/WebIdentity ownership to NIP-IC, but there was no NIP-IC implementation to depend on —zapfhad a hand-rolled, duplicate copy instead. This extracts it intonmilatasnipIC, the same way NIP-AZ was previously extracted, and closes a receipt-tag spoofing gap found while doing so.Test plan
go build ./...,go vet ./...,go test ./...cleannipICtest files cover attestation, identity connection, nconnection encoding, challenge token