sign.go raw
1 package find
2
3 import (
4 "crypto/sha256"
5 "fmt"
6 "time"
7
8 "next.orly.dev/pkg/nostr/encoders/event"
9 "next.orly.dev/pkg/nostr/encoders/hex"
10 "next.orly.dev/pkg/nostr/interfaces/signer"
11 )
12
13 // SignTransferAuth creates a signature for transfer authorization
14 // Message format: transfer:<name>:<new_owner_pubkey>:<timestamp>
15 func SignTransferAuth(name, newOwner string, timestamp time.Time, s signer.I) (string, error) {
16 // Normalize name
17 name = NormalizeName(name)
18
19 // Construct message
20 message := fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
21
22 // Hash the message
23 hash := sha256.Sum256([]byte(message))
24
25 // Sign the hash
26 sig, err := s.Sign(hash[:])
27 if err != nil {
28 return "", fmt.Errorf("failed to sign transfer authorization: %w", err)
29 }
30
31 // Return hex-encoded signature
32 return hex.Enc(sig), nil
33 }
34
35 // SignChallengeProof creates a signature for certificate challenge proof
36 // Message format: challenge||name||cert_pubkey||valid_until
37 func SignChallengeProof(challenge, name, certPubkey string, validUntil time.Time, s signer.I) (string, error) {
38 // Normalize name
39 name = NormalizeName(name)
40
41 // Construct message
42 message := fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
43
44 // Hash the message
45 hash := sha256.Sum256([]byte(message))
46
47 // Sign the hash
48 sig, err := s.Sign(hash[:])
49 if err != nil {
50 return "", fmt.Errorf("failed to sign challenge proof: %w", err)
51 }
52
53 // Return hex-encoded signature
54 return hex.Enc(sig), nil
55 }
56
57 // SignWitnessMessage creates a witness signature for a certificate
58 // Message format: cert_pubkey||name||valid_from||valid_until||challenge
59 func SignWitnessMessage(certPubkey, name string, validFrom, validUntil time.Time, challenge string, s signer.I) (string, error) {
60 // Normalize name
61 name = NormalizeName(name)
62
63 // Construct message
64 message := fmt.Sprintf("%s||%s||%d||%d||%s",
65 certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
66
67 // Hash the message
68 hash := sha256.Sum256([]byte(message))
69
70 // Sign the hash
71 sig, err := s.Sign(hash[:])
72 if err != nil {
73 return "", fmt.Errorf("failed to sign witness message: %w", err)
74 }
75
76 // Return hex-encoded signature
77 return hex.Enc(sig), nil
78 }
79
80 // CreateTransferAuthMessage constructs the transfer authorization message
81 // This is used for verification
82 func CreateTransferAuthMessage(name, newOwner string, timestamp time.Time) []byte {
83 name = NormalizeName(name)
84 message := fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
85 hash := sha256.Sum256([]byte(message))
86 return hash[:]
87 }
88
89 // CreateChallengeProofMessage constructs the challenge proof message
90 // This is used for verification
91 func CreateChallengeProofMessage(challenge, name, certPubkey string, validUntil time.Time) []byte {
92 name = NormalizeName(name)
93 message := fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
94 hash := sha256.Sum256([]byte(message))
95 return hash[:]
96 }
97
98 // CreateWitnessMessage constructs the witness message
99 // This is used for verification
100 func CreateWitnessMessage(certPubkey, name string, validFrom, validUntil time.Time, challenge string) []byte {
101 name = NormalizeName(name)
102 message := fmt.Sprintf("%s||%s||%d||%d||%s",
103 certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
104 hash := sha256.Sum256([]byte(message))
105 return hash[:]
106 }
107
108 // ParseTimestampFromProposal extracts the timestamp from a transfer authorization message
109 // Used for verification when the timestamp is embedded in the signature
110 func ParseTimestampFromProposal(proposalTime time.Time) time.Time {
111 // Round to nearest second for consistency
112 return proposalTime.Truncate(time.Second)
113 }
114
115 // FormatTransferAuthString formats the transfer auth message for display/debugging
116 func FormatTransferAuthString(name, newOwner string, timestamp time.Time) string {
117 name = NormalizeName(name)
118 return fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
119 }
120
121 // FormatChallengeProofString formats the challenge proof message for display/debugging
122 func FormatChallengeProofString(challenge, name, certPubkey string, validUntil time.Time) string {
123 name = NormalizeName(name)
124 return fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
125 }
126
127 // FormatWitnessString formats the witness message for display/debugging
128 func FormatWitnessString(certPubkey, name string, validFrom, validUntil time.Time, challenge string) string {
129 name = NormalizeName(name)
130 return fmt.Sprintf("%s||%s||%d||%d||%s",
131 certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
132 }
133
134 // SignProposal signs a registration proposal event
135 func SignProposal(ev *event.E, s signer.I) error {
136 return ev.Sign(s)
137 }
138
139 // SignAttestation signs an attestation event
140 func SignAttestation(ev *event.E, s signer.I) error {
141 return ev.Sign(s)
142 }
143
144 // SignTrustGraph signs a trust graph event
145 func SignTrustGraph(ev *event.E, s signer.I) error {
146 return ev.Sign(s)
147 }
148
149 // SignNameState signs a name state event
150 func SignNameState(ev *event.E, s signer.I) error {
151 return ev.Sign(s)
152 }
153
154 // SignNameRecord signs a name record event
155 func SignNameRecord(ev *event.E, s signer.I) error {
156 return ev.Sign(s)
157 }
158
159 // SignCertificate signs a certificate event
160 func SignCertificate(ev *event.E, s signer.I) error {
161 return ev.Sign(s)
162 }
163
164 // SignWitnessService signs a witness service event
165 func SignWitnessService(ev *event.E, s signer.I) error {
166 return ev.Sign(s)
167 }
168