package proxy import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "unicode/utf16" "github.com/tidwall/gjson" "github.com/tidwall/sjson" ) const fingerprintSalt = "59cf53e54c78" func computeFingerprint(firstUserMessage string, version string) string { indices := []int{4, 7, 20} runes := utf16.Encode([]rune(firstUserMessage)) var chars string for _, i := range indices { if i < len(runes) { chars += string(rune(runes[i])) } else { chars += "0" } } input := fingerprintSalt + chars + version hash := sha256.Sum256([]byte(input)) return hex.EncodeToString(hash[:])[:3] } func extractFirstUserMessage(body []byte) string { messages := gjson.GetBytes(body, "messages") if !messages.Exists() || !messages.IsArray() { return "" } for _, msg := range messages.Array() { if msg.Get("role").String() != "user" { continue } content := msg.Get("content") if content.Type == gjson.String { return content.String() } if content.IsArray() { for _, block := range content.Array() { if block.Get("type").String() == "text" { return block.Get("text").String() } } } break } return "" } func buildBillingHeader(body []byte, version string) string { userMsg := extractFirstUserMessage(body) fp := computeFingerprint(userMsg, version) return fmt.Sprintf("x-anthropic-billing-header: cc_version=%s.%s; cc_entrypoint=cli; cch=00000;", version, fp) } func injectBillingHeader(body []byte, version string) []byte { header := buildBillingHeader(body, version) billingBlock := map[string]interface{}{"type": "text", "text": header} billingJSON, _ := json.Marshal(billingBlock) existing := gjson.GetBytes(body, "system") if !existing.Exists() { body, _ = sjson.SetRawBytes(body, "system", []byte("["+string(billingJSON)+"]")) return body } if existing.IsArray() { items := make([]json.RawMessage, 0, len(existing.Array())+1) items = append(items, billingJSON) for _, item := range existing.Array() { items = append(items, json.RawMessage(item.Raw)) } systemJSON, _ := json.Marshal(items) body, _ = sjson.SetRawBytes(body, "system", systemJSON) return body } origText := existing.String() origBlock := map[string]string{"type": "text", "text": origText} origJSON, _ := json.Marshal(origBlock) body, _ = sjson.SetRawBytes(body, "system", []byte("["+string(billingJSON)+","+string(origJSON)+"]")) return body }