Skip to content

Commit b9418e1

Browse files
committed
切换数据查询Api,增加静态汇率设置
1 parent 624a4c4 commit b9418e1

5 files changed

Lines changed: 181 additions & 66 deletions

File tree

src/Telegram.CoinConvertBot/BgServices/USDT_TRC20Service.cs

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
using Microsoft.Extensions.Options;
99
using Telegram.Bot;
1010
using Telegram.CoinConvertBot.BgServices.Base;
11-
using Telegram.CoinConvertBot.BgServices.BotHandler;
1211
using Telegram.CoinConvertBot.Domains.Tables;
1312
using Telegram.CoinConvertBot.Extensions;
1413
using Telegram.CoinConvertBot.Helper;
1514
using Telegram.CoinConvertBot.Models;
15+
using Telegram.CoinConvertBot.Models.TronModel;
1616

1717
namespace Telegram.CoinConvertBot.BgServices
1818
{
@@ -21,16 +21,19 @@ public class USDT_TRC20Service : BaseScheduledService
2121
private readonly ILogger<USDT_TRC20Service> _logger;
2222
private readonly IConfiguration _configuration;
2323
private readonly ITelegramBotClient _botClient;
24+
private readonly IHostEnvironment _env;
2425
private readonly IServiceProvider _serviceProvider;
2526

2627
public USDT_TRC20Service(ILogger<USDT_TRC20Service> logger,
2728
IConfiguration configuration,
2829
ITelegramBotClient botClient,
29-
IServiceProvider serviceProvider) : base("USDT-TRC20记录检测", TimeSpan.FromSeconds(30), logger)
30+
IHostEnvironment env,
31+
IServiceProvider serviceProvider) : base("USDT-TRC20记录检测", TimeSpan.FromSeconds(10), logger)
3032
{
3133
_logger = logger;
3234
_configuration = configuration;
3335
_botClient = botClient;
36+
_env = env;
3437
_serviceProvider = serviceProvider;
3538
}
3639

@@ -44,50 +47,61 @@ protected override async Task ExecuteAsync()
4447
var _bindRepository = provider.GetRequiredService<IBaseRepository<TokenBind>>();
4548

4649
var payMinTime = DateTime.Now.AddSeconds(-60 * 5);
47-
var payMaxTime = DateTime.Now;
4850
var addressArray = _configuration.GetSection("Address:USDT-TRC20").Get<string[]>();
4951
if (addressArray.Length == 0)
5052
{
5153
_logger.LogWarning("未配置USDT收款地址!");
5254
return;
5355
}
56+
var ContractAddress = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
57+
var BaseUrl = "https://api.trongrid.io";
58+
if (!_env.IsProduction())
59+
{
60+
ContractAddress = "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs";
61+
BaseUrl = "https://api.shasta.trongrid.io";
62+
}
5463
foreach (var address in addressArray)
5564
{
5665

57-
var data = new
58-
{
59-
start = 0,
60-
limit = 200,
61-
direction = "in",
62-
tokens = _myTronConfig.Value.USDTContractAddress,
63-
relatedAddress = address,
64-
toAddress = address,
65-
start_timestamp = (long)payMinTime.ToUnixTimeStamp(),
66-
end_timestamp = (long)payMaxTime.ToUnixTimeStamp()
67-
};
68-
var transfers = await _myTronConfig.Value.ApiHost
69-
.AppendPathSegment("api/token_trc20/transfers")
70-
.SetQueryParams(data)
71-
.GetJsonAsync();
72-
if (transfers.total > 0)
66+
var query = new Dictionary<string, object>();
67+
query.Add("only_confirmed", true);
68+
query.Add("only_to", true);
69+
query.Add("limit", 50);
70+
query.Add("min_timestamp", (long)payMinTime.ToUnixTimeStamp());
71+
query.Add("contract_address", ContractAddress);
72+
var req = BaseUrl
73+
.AppendPathSegment($"v1/accounts/{address}/transactions/trc20")
74+
.SetQueryParams(query)
75+
.WithTimeout(15);
76+
if (_env.IsProduction())
77+
req = req.WithHeader("TRON-PRO-API-KEY", _configuration.GetValue("TRON-PRO-API-KEY", ""));
78+
var result = await req
79+
.GetJsonAsync<BaseResponse<Transactions>>();
80+
81+
if (result.Success && result.Data?.Count > 0)
7382
{
74-
var list = (IList<dynamic>)transfers.token_transfers;
75-
foreach (var item in list)
83+
foreach (var item in result.Data)
7684
{
77-
//收款地址相同,已确认的订单
78-
if (item.to_address != address || item.finalResult != "SUCCESS") continue;
85+
//合约地址不匹配
86+
if (item.TokenInfo?.Address != ContractAddress)
87+
{
88+
continue;
89+
}
90+
//收款地址相同
91+
if (item.To != address) continue;
7992
//实际支付金额
80-
var amount = Convert.ToDecimal(item.quant) / 1_000_000;
93+
var amount = item.Amount;
8194
var record = new TokenRecord
8295
{
83-
BlockTransactionId = item.transaction_id,
84-
FromAddress = item.from_address,
85-
ToAddress = item.to_address,
96+
BlockTransactionId = item.TransactionId,
97+
FromAddress = item.From,
98+
ToAddress = item.To,
99+
//ContractAddress = item.TokenInfo.Address,
86100
OriginalAmount = amount,
87101
OriginalCurrency = Currency.USDT,
88102
ConvertCurrency = Currency.TRX,
89103
Status = Status.Pending,
90-
ReceiveTime = ((long)item.block_ts).ToDateTime()
104+
ReceiveTime = item.BlockTimestamp.ToDateTime()
91105
};
92106
if (!await _repository.Where(x => x.BlockTransactionId == record.BlockTransactionId).AnyAsync())
93107
{
@@ -96,7 +110,7 @@ protected override async Task ExecuteAsync()
96110
var AdminUserId = _configuration.GetValue<long>("BotConfig:AdminUserId");
97111
try
98112
{
99-
var viewUrl = $"https://nile.tronscan.org/#/transaction/{record.BlockTransactionId}";
113+
var viewUrl = $"https://shasta.tronscan.org/#/transaction/{record.BlockTransactionId}";
100114
if (hostEnvironment.IsProduction())
101115
{
102116
viewUrl = $"https://tronscan.org/#/transaction/{record.BlockTransactionId}";
@@ -109,21 +123,19 @@ protected override async Task ExecuteAsync()
109123
Bot.Types.ReplyMarkups.InlineKeyboardButton.WithUrl("查看区块",viewUrl),
110124
},
111125
});
112-
var _rateRepository = provider.GetRequiredService<IBaseRepository<TokenRate>>();
113-
var rate = await _rateRepository.Where(x => x.Currency == Currency.USDT && x.ConvertCurrency == Currency.TRX).FirstAsync(x => x.Rate);
126+
114127
var binds = await _bindRepository.Where(x => x.Currency == Currency.TRX && x.Address == record.FromAddress).ToListAsync();
115128
if (binds.Count > 0)
116129
{
117130
foreach (var bind in binds)
118131
{
119132
try
120133
{
121-
await _botClient.SendTextMessageAsync(bind.UserId, $@"<b>我们已经收到您的USDT</b>
134+
await _botClient.SendTextMessageAsync(bind.UserId, $@"<b>我们已经收到您转出的USDT</b>
122135
金额:<b>{record.OriginalAmount:#.######} {record.OriginalCurrency}</b>
123136
哈希:<code>{record.BlockTransactionId}</code>
124137
时间:<b>{record.ReceiveTime:yyyy-MM-dd HH:mm:ss}</b>
125138
地址:<code>{record.FromAddress}</code>
126-
预估:<b>{record.OriginalAmount.USDT_To_TRX(rate, UpdateHandlers.FeeRate)} TRX</b>
127139
128140
您的兑换申请已进入队列,预计5分钟内转入您的账户!
129141
", Bot.Types.Enums.ParseMode.Html, replyMarkup: inlineKeyboard);
@@ -136,13 +148,17 @@ await _botClient.SendTextMessageAsync(bind.UserId, $@"<b>我们已经收到您
136148
}
137149
if (AdminUserId > 0)
138150
{
151+
var _rateRepository = provider.GetRequiredService<IBaseRepository<TokenRate>>();
152+
var rate = await _rateRepository.Where(x => x.Currency == Currency.USDT && x.ConvertCurrency == Currency.TRX).FirstAsync(x => x.Rate);
139153
await _botClient.SendTextMessageAsync(AdminUserId, $@"<b>USDT入账通知!({record.OriginalAmount:#.######} {record.OriginalCurrency})</b>
140154
141155
订单:<code>{record.BlockTransactionId}</code>
156+
原币:<b>{record.OriginalCurrency}</b>
142157
转入:<b>{record.OriginalAmount:#.######} {record.OriginalCurrency}</b>
143158
来源:<code>{record.FromAddress}</code>
144159
接收:<code>{record.ToAddress}</code>
145-
预估:<b>{record.OriginalAmount.USDT_To_TRX(rate, UpdateHandlers.FeeRate)} TRX</b>
160+
转换:<b>{record.ConvertCurrency}</b>
161+
预估:<b>{record.OriginalAmount.USDT_To_TRX(rate)} TRX</b>
146162
时间:<b>{record.ReceiveTime:yyyy-MM-dd HH:mm:ss}</b>
147163
", Bot.Types.Enums.ParseMode.Html, replyMarkup: inlineKeyboard);
148164
}

src/Telegram.CoinConvertBot/BgServices/UpdateRateService.cs

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,50 +38,66 @@ public UpdateRateService(
3838

3939
protected override async Task ExecuteAsync()
4040
{
41+
var list = new List<TokenRate>();
4142
_logger.LogInformation("------------------{tips}------------------", "开始更新汇率");
4243
using IServiceScope scope = _serviceProvider.CreateScope();
4344
var _repository = scope.ServiceProvider.GetRequiredService<IBaseRepository<TokenRate>>();
4445

45-
var list = new List<TokenRate>();
46-
var side = "buy";
47-
try
46+
var rate = _configuration.GetValue("TrxRate", 0m);
47+
if (rate > 0)
48+
{
49+
list.Add(new TokenRate
50+
{
51+
Id = $"USDT_{Currency.TRX}",
52+
Currency = Currency.USDT,
53+
ConvertCurrency = Currency.TRX,
54+
LastUpdateTime = DateTime.Now,
55+
Rate = rate,
56+
ReverseRate = 1m / rate,
57+
});
58+
}
59+
else
4860
{
61+
var side = "buy";
62+
try
63+
{
4964

50-
var convert1 = await baseUrl
51-
.WithClient(client)
52-
.WithHeaders(new { User_Agent })
53-
.AppendPathSegment("v2/asset/quick/exchange/quote")
54-
//.SetQueryParams()
55-
.PostJsonAsync(new
65+
var convert1 = await baseUrl
66+
.WithClient(client)
67+
.WithHeaders(new { User_Agent })
68+
.AppendPathSegment("v2/asset/quick/exchange/quote")
69+
//.SetQueryParams()
70+
.PostJsonAsync(new
71+
{
72+
side,
73+
baseCcy = Currency.TRX.ToString(),
74+
quoteCcy = Currency.USDT.ToString(),
75+
rfqSz = 1,
76+
rfqSzCcy = Currency.USDT.ToString(),
77+
})
78+
.ReceiveJson<Root>();
79+
if (convert1.code == 0)
5680
{
57-
side,
58-
baseCcy = Currency.TRX.ToString(),
59-
quoteCcy = Currency.USDT.ToString(),
60-
rfqSz = 1,
61-
rfqSzCcy = Currency.USDT.ToString(),
62-
})
63-
.ReceiveJson<Root>();
64-
if (convert1.code == 0)
65-
{
66-
list.Add(new TokenRate
81+
list.Add(new TokenRate
82+
{
83+
Id = $"USDT_{Currency.TRX}",
84+
Currency = Currency.USDT,
85+
ConvertCurrency = Currency.TRX,
86+
LastUpdateTime = DateTime.Now,
87+
Rate = convert1.data.askBaseSz,
88+
ReverseRate = convert1.data.askPx,
89+
});
90+
}
91+
else
6792
{
68-
Id = $"USDT_{Currency.TRX}",
69-
Currency = Currency.USDT,
70-
ConvertCurrency = Currency.TRX,
71-
LastUpdateTime = DateTime.Now,
72-
Rate = convert1.data.askBaseSz,
73-
ReverseRate = convert1.data.askPx,
74-
});
93+
//_logger.LogWarning("TRX -> USDT 汇率获取失败!错误信息:{msg}", convert1.msg ?? convert1.error_message);
94+
}
7595
}
76-
else
96+
catch (Exception e)
7797
{
78-
//_logger.LogWarning("TRX -> USDT 汇率获取失败!错误信息:{msg}", convert1.msg ?? convert1.error_message);
98+
_logger.LogWarning("TRX -> USDT 汇率获取失败!错误信息:{msg}", e?.InnerException?.Message + "; " + e?.Message);
7999
}
80100
}
81-
catch (Exception e)
82-
{
83-
_logger.LogWarning("TRX -> USDT 汇率获取失败!错误信息:{msg}", e?.InnerException?.Message + "; " + e?.Message);
84-
}
85101

86102
foreach (var item in list)
87103
{
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Text.Json.Serialization;
7+
using System.Threading.Tasks;
8+
9+
namespace Telegram.CoinConvertBot.Models.TronModel
10+
{
11+
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
12+
public class Meta
13+
{
14+
[JsonProperty("at")]
15+
public long At { get; set; }
16+
17+
[JsonProperty("page_size")]
18+
public int PageSize { get; set; }
19+
}
20+
21+
public class BaseResponse<T>
22+
{
23+
[JsonProperty("data")]
24+
public List<T> Data { get; set; }
25+
26+
[JsonProperty("success")]
27+
public bool Success { get; set; }
28+
29+
[JsonProperty("meta")]
30+
public Meta Meta { get; set; }
31+
}
32+
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Telegram.CoinConvertBot.Models.TronModel
4+
{
5+
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
6+
public class Transactions
7+
{
8+
[JsonProperty("transaction_id")]
9+
public string TransactionId { get; set; }
10+
11+
[JsonProperty("token_info")]
12+
public TokenInfo TokenInfo { get; set; }
13+
14+
[JsonProperty("block_timestamp")]
15+
public long BlockTimestamp { get; set; }
16+
17+
[JsonProperty("from")]
18+
public string From { get; set; }
19+
20+
[JsonProperty("to")]
21+
public string To { get; set; }
22+
23+
[JsonProperty("type")]
24+
public string Type { get; set; }
25+
26+
[JsonProperty("value")]
27+
public decimal Value { get; set; }
28+
/// <summary>
29+
/// 实际USDT金额,需要计算精度
30+
/// </summary>
31+
public decimal Amount => Value / 1_000_000;
32+
}
33+
34+
public class TokenInfo
35+
{
36+
[JsonProperty("symbol")]
37+
public string Symbol { get; set; }
38+
39+
[JsonProperty("address")]
40+
public string Address { get; set; }
41+
42+
[JsonProperty("decimals")]
43+
public int Decimals { get; set; }
44+
45+
[JsonProperty("name")]
46+
public string Name { get; set; }
47+
}
48+
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
49+
}

src/Telegram.CoinConvertBot/appsettings.Example.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@
3737
"MinToken": {
3838
"USDT": 5 //最小兑换USDT数量
3939
},
40+
"TrxRate": 0,//1 USDT兑换的TRX汇率,不设置或设为0使用实时汇率
4041
"FeeRate": 0.1 //从最终用户获取的TRX中的抽成比例,默认10%
4142
}

0 commit comments

Comments
 (0)