diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/client/crypto.go | 235 | ||||
| -rw-r--r-- | internal/client/email.go | 28 | ||||
| -rw-r--r-- | internal/client/telegram.go | 28 | ||||
| -rw-r--r-- | internal/formatter/crypto.go | 39 | ||||
| -rw-r--r-- | internal/formatter/email.go | 103 | ||||
| -rw-r--r-- | internal/formatter/telegram.go | 34 | ||||
| -rw-r--r-- | internal/models/admin.go | 19 | ||||
| -rw-r--r-- | internal/models/crypto.go | 12 | ||||
| -rw-r--r-- | internal/models/email.go | 21 | ||||
| -rw-r--r-- | internal/models/github.go | 1 | ||||
| -rw-r--r-- | internal/models/telegram.go | 12 |
11 files changed, 523 insertions, 9 deletions
diff --git a/internal/client/crypto.go b/internal/client/crypto.go new file mode 100644 index 0000000..ee145f9 --- /dev/null +++ b/internal/client/crypto.go @@ -0,0 +1,235 @@ +package client + +import ( + "encoding/json" + "fmt" + "git.db.org.ai/dborg/internal/models" + "strings" +) + +func (c *Client) GetBundleDetection(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/bundle-detection/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetCrossTraders(addresses string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/cross-traders/%s", addresses) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetEarlyAdopters(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/early-adopters/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetFloorHolders(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/floor-holders/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetFreshAccounts(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/fresh-accounts/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetFundingSource(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/funding-source/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetGraduationStats() (*models.CryptoResponse, error) { + data, err := c.Get("/crypto/graduation-stats", nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetLaunchParticipants(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/launch-participants/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetLiquidity(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/liquidity/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetOwnerIntel(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/owner-intel/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetOwnershipDistribution(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/ownership-distribution/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetPortfolio(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/portfolio/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetTopOwners(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/top-owners/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func (c *Client) GetWhaleIntel(address string) (*models.CryptoResponse, error) { + path := fmt.Sprintf("/crypto/whale-intel/%s", address) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.CryptoResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse crypto response: %w", err) + } + + return &response, nil +} + +func ValidateCryptoAddress(address string) error { + if len(address) == 0 { + return fmt.Errorf("address cannot be empty") + } + return nil +} + +func ValidateCryptoAddresses(addresses string) error { + if len(addresses) == 0 { + return fmt.Errorf("addresses cannot be empty") + } + parts := strings.Split(addresses, ",") + if len(parts) < 2 { + return fmt.Errorf("at least 2 addresses required for cross-trader analysis") + } + return nil +} diff --git a/internal/client/email.go b/internal/client/email.go new file mode 100644 index 0000000..a7000fe --- /dev/null +++ b/internal/client/email.go @@ -0,0 +1,28 @@ +package client + +import ( + "encoding/json" + "fmt" + "git.db.org.ai/dborg/internal/models" + "strings" +) + +func (c *Client) VerifyEmail(email string) (*models.EmailVerifyResponse, error) { + email = strings.TrimSpace(email) + if email == "" { + return nil, fmt.Errorf("email address cannot be empty") + } + + path := fmt.Sprintf("/email/verify/%s", email) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.EmailVerifyResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse email verification response: %w", err) + } + + return &response, nil +} diff --git a/internal/client/telegram.go b/internal/client/telegram.go new file mode 100644 index 0000000..33b4ac2 --- /dev/null +++ b/internal/client/telegram.go @@ -0,0 +1,28 @@ +package client + +import ( + "encoding/json" + "fmt" + "git.db.org.ai/dborg/internal/models" + "strings" +) + +func (c *Client) GetTelegramPhone(identifier string) (*models.TelegramPhoneResponse, error) { + identifier = strings.TrimSpace(identifier) + if identifier == "" { + return nil, fmt.Errorf("identifier cannot be empty") + } + + path := fmt.Sprintf("/telegram/phone/%s", identifier) + data, err := c.Get(path, nil) + if err != nil { + return nil, err + } + + var response models.TelegramPhoneResponse + if err := json.Unmarshal(data, &response); err != nil { + return nil, fmt.Errorf("failed to parse telegram response: %w", err) + } + + return &response, nil +} diff --git a/internal/formatter/crypto.go b/internal/formatter/crypto.go new file mode 100644 index 0000000..70ef29b --- /dev/null +++ b/internal/formatter/crypto.go @@ -0,0 +1,39 @@ +package formatter + +import ( + "fmt" + "git.db.org.ai/dborg/internal/models" + "git.db.org.ai/dborg/internal/utils" + "strings" +) + +func FormatCryptoResults(response *models.CryptoResponse, asJSON bool) error { + if asJSON { + return utils.PrintJSON(response) + } + + PrintSection(fmt.Sprintf("📊 Crypto Analysis Results")) + + if response.Query != "" { + fmt.Printf("%s: %s\n\n", Cyan("Query"), response.Query) + } + + if response.Response != "" { + fmt.Println(response.Response) + fmt.Println() + } + + PrintDivider() + fmt.Printf("%s: ", Cyan("Credits Remaining")) + if response.Credits.Unlimited { + fmt.Printf("%s\n", Green("Unlimited")) + } else { + fmt.Printf("%s\n", FormatCredits(int64(response.Credits.Remaining))) + } + + if response.Message != "" && !strings.Contains(strings.ToLower(response.Message), "success") { + fmt.Printf("\n%s: %s\n", Yellow("Message"), response.Message) + } + + return nil +} diff --git a/internal/formatter/email.go b/internal/formatter/email.go new file mode 100644 index 0000000..80f590c --- /dev/null +++ b/internal/formatter/email.go @@ -0,0 +1,103 @@ +package formatter + +import ( + "fmt" + "git.db.org.ai/dborg/internal/models" + "git.db.org.ai/dborg/internal/utils" +) + +func FormatEmailResults(response *models.EmailVerifyResponse, asJSON bool) error { + if asJSON { + return utils.PrintJSON(response) + } + + PrintSection(fmt.Sprintf("📧 Email Verification: %s", Bold(response.Email))) + + statusColor := ColorGreen + switch response.Status { + case "valid": + statusColor = ColorGreen + case "invalid": + statusColor = ColorRed + case "risky", "accept_all": + statusColor = ColorYellow + default: + statusColor = ColorGray + } + + fmt.Printf("%s: %s", Cyan("Status"), Colorize(response.Status, statusColor)) + if response.Score > 0 { + scoreColor := ColorGreen + if response.Score < 50 { + scoreColor = ColorRed + } else if response.Score < 75 { + scoreColor = ColorYellow + } + fmt.Printf(" (Score: %s)", Colorize(fmt.Sprintf("%d/100", response.Score), scoreColor)) + } + fmt.Println() + + fmt.Println() + fmt.Printf("%s\n", Bold("Validation Checks")) + + checks := []struct { + name string + passed bool + }{ + {"Format Valid", response.Regexp}, + {"MX Records Found", response.MXRecords}, + {"SMTP Server Reachable", response.SMTPServer}, + {"Mailbox Verified", response.SMTPCheck}, + } + + for _, check := range checks { + status := StatusError + if check.passed { + status = StatusSuccess + } + fmt.Printf(" %s %s\n", status.String(), check.name) + } + + if response.MXServer != "" { + fmt.Printf("\n%s: %s\n", Cyan("MX Server"), response.MXServer) + } + + fmt.Println() + fmt.Printf("%s\n", Bold("Risk Indicators")) + + risks := []struct { + name string + present bool + }{ + {"Disposable Email", response.Disposable}, + {"Webmail Service", response.Webmail}, + {"Blocked Domain", response.Block}, + {"Gibberish Detected", response.Gibberish}, + } + + hasRisks := false + for _, risk := range risks { + if risk.present { + hasRisks = true + fmt.Printf(" %s %s\n", StatusWarning.String(), risk.name) + } + } + + if !hasRisks { + fmt.Printf(" %s %s\n", StatusSuccess.String(), "No risk indicators found") + } + + if response.ResponseTimeMs > 0 { + fmt.Printf("\n%s: %dms\n", Dim("Response Time"), response.ResponseTimeMs) + } + + if response.ErrorMessage != "" { + fmt.Printf("\n%s: %s\n", Red("Error"), response.ErrorMessage) + } + + if response.VerifiedAt != "" { + fmt.Printf("%s: %s\n", Dim("Verified At"), response.VerifiedAt) + } + + return nil +} diff --git a/internal/formatter/telegram.go b/internal/formatter/telegram.go new file mode 100644 index 0000000..7491c66 --- /dev/null +++ b/internal/formatter/telegram.go @@ -0,0 +1,34 @@ +package formatter + +import ( + "fmt" + "git.db.org.ai/dborg/internal/models" + "git.db.org.ai/dborg/internal/utils" +) + +func FormatTelegramResults(response *models.TelegramPhoneResponse, asJSON bool) error { + if asJSON { + return utils.PrintJSON(response) + } + + PrintSection(fmt.Sprintf("📱 Telegram Phone Lookup")) + + fmt.Printf("%s: %s\n", Cyan("Identifier"), response.Identifier) + + if response.PhoneNumber != "" { + fmt.Printf("%s: %s\n", Cyan("Phone Number"), Green(response.PhoneNumber)) + } else { + fmt.Printf("%s: %s\n", Cyan("Phone Number"), Red("Not found")) + } + + fmt.Println() + PrintDivider() + fmt.Printf("%s: ", Cyan("Credits Remaining")) + if response.Credits.Unlimited { + fmt.Printf("%s\n", Green("Unlimited")) + } else { + fmt.Printf("%s\n", FormatCredits(int64(response.Credits.Remaining))) + } + + return nil +} diff --git a/internal/models/admin.go b/internal/models/admin.go index 852e80f..ee551f3 100644 --- a/internal/models/admin.go +++ b/internal/models/admin.go @@ -1,15 +1,16 @@ package models type Account struct { - ID int `json:"id"` - APIKey string `json:"api_key"` - Name string `json:"name"` - Credits int `json:"credits"` - Unlimited bool `json:"unlimited"` - Disabled bool `json:"disabled"` - IsPremium bool `json:"is_premium"` - IsAdmin bool `json:"is_admin"` - CreatedAt interface{} `json:"created_at,omitempty"` + ID int `json:"id"` + APIKey string `json:"api_key"` + Name string `json:"name"` + Credits int `json:"credits"` + Unlimited bool `json:"unlimited"` + Disabled bool `json:"disabled"` + IsPremium bool `json:"is_premium"` + IsAdmin bool `json:"is_admin"` + PremiumDiscountPct int `json:"premium_discount_pct,omitempty"` + CreatedAt interface{} `json:"created_at,omitempty"` } type AccountCreateRequest struct { diff --git a/internal/models/crypto.go b/internal/models/crypto.go new file mode 100644 index 0000000..1900037 --- /dev/null +++ b/internal/models/crypto.go @@ -0,0 +1,12 @@ +package models + +type CryptoResponse struct { + Query string `json:"query"` + Response string `json:"response"` + Credits struct { + Remaining int `json:"remaining"` + Unlimited bool `json:"unlimited"` + } `json:"credits"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/internal/models/email.go b/internal/models/email.go new file mode 100644 index 0000000..0b95e85 --- /dev/null +++ b/internal/models/email.go @@ -0,0 +1,21 @@ +package models + +type EmailVerifyResponse struct { + Email string `json:"email"` + Status string `json:"status"` + Score int `json:"score"` + Regexp bool `json:"regexp"` + MXRecords bool `json:"mx_records"` + MXServer string `json:"mx_server,omitempty"` + SMTPServer bool `json:"smtp_server"` + SMTPCheck bool `json:"smtp_check"` + Disposable bool `json:"disposable"` + Webmail bool `json:"webmail"` + Block bool `json:"block"` + Gibberish bool `json:"gibberish"` + ErrorMessage string `json:"error_message,omitempty"` + VerifiedAt string `json:"verified_at,omitempty"` + ResponseTimeMs int `json:"response_time_ms"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` +} diff --git a/internal/models/github.go b/internal/models/github.go index fc1c9c3..3b7fc73 100644 --- a/internal/models/github.go +++ b/internal/models/github.go @@ -9,4 +9,5 @@ type GitHubLead struct { Website string `json:"website,omitempty"` Twitter string `json:"twitter,omitempty"` PFP string `json:"pfp,omitempty"` + Bio string `json:"bio,omitempty"` } diff --git a/internal/models/telegram.go b/internal/models/telegram.go new file mode 100644 index 0000000..05900cb --- /dev/null +++ b/internal/models/telegram.go @@ -0,0 +1,12 @@ +package models + +type TelegramPhoneResponse struct { + Identifier string `json:"identifier"` + PhoneNumber string `json:"phone_number"` + Credits struct { + Remaining int `json:"remaining"` + Unlimited bool `json:"unlimited"` + } `json:"credits"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` +} |
