package tron import ( "encoding/hex" "strings" "code.luxferre.top/luxferre/kisstron/base58" ) // ToBase58CheckAddress converts an address given in any accepted format // (base58check, 41-prefixed hex, or 0x-prefixed hex) to its base58check // representation, verifying the checksum. The argument may be a string or a // byte slice. func ToBase58CheckAddress(raw any) (string, error) { switch v := raw.(type) { case string: return strToBase58Check(v) case []byte: return bytesToBase58Check(v) } return "", ErrBadAddress } func strToBase58Check(s string) (string, error) { if len(s) == 0 { return "", ErrBadAddress } if s[0] == 'T' && len(s) == 34 { if !base58.IsValid(s) { return "", ErrBadAddress } return s, nil } if len(s) == 42 { if strings.HasPrefix(s, "0x") { b, err := hex.DecodeString(s[2:]) if err != nil || len(b) != 20 { return "", ErrBadAddress } return base58.CheckEncode(append([]byte{0x41}, b...)), nil } b, err := hex.DecodeString(s) if err != nil || len(b) != 21 { return "", ErrBadAddress } return base58.CheckEncode(b), nil } if strings.HasPrefix(s, "0x") && len(s) == 44 { b, err := hex.DecodeString(s[2:]) if err != nil || len(b) != 21 { return "", ErrBadAddress } return base58.CheckEncode(b), nil } return "", ErrBadAddress } func bytesToBase58Check(b []byte) (string, error) { switch { case len(b) == 21 && b[0] == 0x41: return base58.CheckEncode(b), nil case len(b) == 20: return base58.CheckEncode(append([]byte{0x41}, b...)), nil default: return strToBase58Check(string(b)) } } // ToHexAddress converts an address to its 41-prefixed hex representation. func ToHexAddress(raw any) (string, error) { addr, err := ToBase58CheckAddress(raw) if err != nil { return "", err } b, err := base58.CheckDecode(addr) if err != nil { return "", ErrBadAddress } return hex.EncodeToString(b), nil } // ToRawAddress returns the 21-byte raw form of an address. func ToRawAddress(raw any) ([]byte, error) { addr, err := ToBase58CheckAddress(raw) if err != nil { return nil, err } return base58.CheckDecode(addr) } // ToTvmAddress returns the 20-byte TVM (Ethereum-style) form of an address. func ToTvmAddress(raw any) ([]byte, error) { b, err := ToRawAddress(raw) if err != nil { return nil, err } return b[1:], nil } // IsBase58CheckAddress reports whether value is a valid base58check address. func IsBase58CheckAddress(value string) bool { if len(value) == 0 || value[0] != 'T' { return false } b, err := base58.CheckDecode(value) return err == nil && len(b) == 21 } // IsHexAddress reports whether value is a valid 41-prefixed hex address. func IsHexAddress(value string) bool { if !strings.HasPrefix(value, "41") { return false } b, err := hex.DecodeString(value) return err == nil && len(b) == 21 } // IsAddress reports whether value is any accepted TRON address format. func IsAddress(value string) bool { return IsBase58CheckAddress(value) || IsHexAddress(value) }