diff --git a/TonSdk.Client/src/Client/ITonClient.cs b/TonSdk.Client/src/Client/ITonClient.cs index 8cf4b18..f6a6223 100644 --- a/TonSdk.Client/src/Client/ITonClient.cs +++ b/TonSdk.Client/src/Client/ITonClient.cs @@ -93,15 +93,26 @@ public interface ITonClient /// /// Retrieves transaction information for the specified address. /// - /// The address object to retrieve transaction information for. + /// The address object to retrieve transaction information for (optional for HTTP_TONCENTERAPIV3). + /// Block workchain (optional). + /// Block shard id. Must be sent with workchain (optional). + /// Block block seqno. Must be sent with workchain and shard (optional). /// The maximum number of transactions to retrieve (default: 10). /// The logical time of the transaction to start retrieving from (optional). /// The hash of the transaction to start retrieving from (optional). /// The logical time of the transaction to retrieve up to (optional). /// Specifies whether to retrieve transactions from archival nodes (optional). /// An array of transaction information results. - Task GetTransactions(Address address, uint limit = 10, - ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null); + Task GetTransactions( + Address address = null, + int? workchain = null, + long? shard = null, + long? seqno = null, + uint limit = 10, + ulong? lt = null, + string hash = null, + ulong? to_lt = null, + bool? archival = null); /// /// Executes a specific method on the specified address. diff --git a/TonSdk.Client/src/Client/Jetton/Jetton.cs b/TonSdk.Client/src/Client/Jetton/Jetton.cs index bbba83f..c01d95e 100644 --- a/TonSdk.Client/src/Client/Jetton/Jetton.cs +++ b/TonSdk.Client/src/Client/Jetton/Jetton.cs @@ -136,7 +136,7 @@ await JettonUtils.ParseMetadata(((VmStackCell)result.Value.StackItems[3]).Value) /// An array of parsed jetton transactions. public async Task GetTransactions(Address jettonWallet, int limit = 5, uint? decimals = null, BlockIdExtended? block = null) { - TransactionsInformationResult[] transactionsInformationResults = await client.GetTransactions(jettonWallet, (uint)limit); + TransactionsInformationResult[] transactionsInformationResults = await client.GetTransactions(address: jettonWallet, limit: (uint)limit); uint jettonDecimals = decimals ?? await GetDecimalsByWallet(jettonWallet, block); IJettonTransaction[] parsedTransactions = new IJettonTransaction[transactionsInformationResults.Length]; diff --git a/TonSdk.Client/src/Client/TonClient.cs b/TonSdk.Client/src/Client/TonClient.cs index ddac382..87eac06 100644 --- a/TonSdk.Client/src/Client/TonClient.cs +++ b/TonSdk.Client/src/Client/TonClient.cs @@ -249,24 +249,31 @@ public async Task IsContractDeployed(Address address, BlockIdExtended? blo /// /// Retrieves transaction information for the specified address. /// - /// The address object to retrieve transaction information for. + /// The address object to retrieve transaction information for (optional for HTTP_TONCENTERAPIV3). + /// Block workchain (optional). + /// Block shard id. Must be sent with workchain (optional). + /// Block block seqno. Must be sent with workchain and shard (optional). /// The maximum number of transactions to retrieve (default: 10). /// The logical time of the transaction to start retrieving from (optional). /// The hash of the transaction to start retrieving from (optional). /// The logical time of the transaction to retrieve up to (optional). /// Specifies whether to retrieve transactions from archival nodes (optional). /// An array of transaction information results. - public async Task GetTransactions(Address address, uint limit = 10, - ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) + public async Task GetTransactions(Address address = null, + int? workchain = null, long? shard = null, long? seqno = null, + uint limit = 10, ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) { if(_type == TonClientType.LITECLIENT && (lt == null || hash == null)) throw new ArgumentException("From lt and hash, must be defined for LiteClient type."); + if (_type != TonClientType.HTTP_TONCENTERAPIV3 && (workchain != null || shard != null || seqno != null)) + throw new ArgumentException($"Workchain, shard and seqno parameters are not supported for {_type} client type."); + return _type switch { TonClientType.HTTP_TONCENTERAPIV2 => await _httpApi.GetTransactions(address, limit, lt, hash, to_lt, archival), TonClientType.HTTP_TONWHALESAPI => await _httpWhales.GetTransactions(address, limit, lt, hash, to_lt, archival), - TonClientType.HTTP_TONCENTERAPIV3 => await _httpApiV3.GetTransactions(address, limit, lt, hash, to_lt, archival), + TonClientType.HTTP_TONCENTERAPIV3 => await _httpApiV3.GetTransactions(address, workchain, shard, seqno, limit, lt, hash, to_lt, archival), TonClientType.LITECLIENT => await _liteClientApi.GetTransactions(address, limit, (long)lt, hash), _ => null }; diff --git a/TonSdk.Client/src/HttpApi/HttpsApi.cs b/TonSdk.Client/src/HttpApi/HttpsApi.cs index fda9b9e..cd83814 100644 --- a/TonSdk.Client/src/HttpApi/HttpsApi.cs +++ b/TonSdk.Client/src/HttpApi/HttpsApi.cs @@ -138,6 +138,9 @@ internal async Task GetBlockTransactions( internal async Task GetTransactions(Address address, uint limit = 10, ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) { + if (address is null) + throw new ArgumentException($"Address must be defined for {nameof(TonClientType.HTTP_TONCENTERAPIV2)} client type."); + InTransactionsBody requestBody = new InTransactionsBody() { address = address.ToString(AddressType.Base64, new AddressStringifyOptions(true, false, false)), diff --git a/TonSdk.Client/src/HttpApi/HttpsApiV3.cs b/TonSdk.Client/src/HttpApi/HttpsApiV3.cs index 40d1758..b1abb27 100644 --- a/TonSdk.Client/src/HttpApi/HttpsApiV3.cs +++ b/TonSdk.Client/src/HttpApi/HttpsApiV3.cs @@ -112,30 +112,11 @@ internal async Task Shards(long seqno) return new ShardsInformationResult(JsonConvert.DeserializeObject(result)); } - internal async Task GetTransactions(Address address, uint limit = 10, - ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) + internal async Task GetTransactions(Address address = null, + int? workchain = null, long? shard = null, long? seqno = null, + uint limit = 10, ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) { - var dict = new Dictionary() - { - { - "account", address.ToString() - }, - { - "offset", "0" - }, - { - "limit", limit.ToString() - }, - { - "sort", "desc" - } - }; - - if (lt != null) - dict.Add("start_lt", lt.ToString()); - if (to_lt != null) - dict.Add("end_lt", to_lt.ToString()); - + var dict = BuildGetTransactionsRequestParameters(workchain, shard, seqno, address, hash, lt, to_lt, limit); string result = await new TonRequestV3(new RequestParametersV3("transactions", dict), _httpClient).CallGet(); var data = JsonConvert.DeserializeObject(result).Transactions; @@ -154,31 +135,7 @@ internal async Task GetBlockTransactions( { try { - var dict = new Dictionary() - { - { - "workchain", workchain.ToString() - }, - { - "shard", shard.ToString("X") - }, - { - "seqno", seqno.ToString() - }, - { - "offset", "0" - }, - { - "limit", count != null ? count.ToString() : "10" - }, - { - "sort", "desc" - } - }; - - if (afterLt != null) - dict.Add("start_lt", afterLt.ToString()); - + var dict = BuildGetTransactionsRequestParameters(workchain: workchain, shard: shard, seqno: seqno, startLt: afterLt, limit: count ?? 10); string result = await new TonRequestV3(new RequestParametersV3("transactions", dict), _httpClient).CallGet(); var data = JsonConvert.DeserializeObject(result).Transactions; @@ -269,6 +226,40 @@ internal async Task EstimateFee(MessageX message, boo return JsonConvert.DeserializeObject(result); } + + private Dictionary BuildGetTransactionsRequestParameters( + int? workchain = null, + long? shard = null, + long? seqno = null, + Address address = null, + string hash = null, + ulong? startLt = null, + ulong? endLt = null, + uint limit = 10, + int offset = 0, + SortDirection sort = SortDirection.DESC) + { + var queryParameters = new Dictionary + { + { "offset", offset.ToString() }, + { "limit", limit.ToString() }, + { "sort", sort.ToString().ToLower() } + }; + + if (workchain.HasValue) queryParameters.Add("workchain", workchain.ToString()); + if (shard.HasValue) queryParameters.Add("shard", shard.Value.ToString("X")); + if (seqno.HasValue) queryParameters.Add("seqno", seqno.ToString()); + + if (address != null) + queryParameters.Add("account", address.ToString(AddressType.Raw)); + + if (!string.IsNullOrEmpty(hash)) queryParameters.Add("hash", hash); + + if (startLt != null) queryParameters.Add("start_lt", startLt.ToString()); + if (endLt != null) queryParameters.Add("end_lt", endLt.ToString()); + + return queryParameters; + } public async Task CustomGetMethodCall(string request, List body) { diff --git a/TonSdk.Client/src/HttpApi/HttpsWhales.cs b/TonSdk.Client/src/HttpApi/HttpsWhales.cs index 41bc985..fa20345 100644 --- a/TonSdk.Client/src/HttpApi/HttpsWhales.cs +++ b/TonSdk.Client/src/HttpApi/HttpsWhales.cs @@ -132,6 +132,9 @@ internal async Task GetBlockTransactions( internal async Task GetTransactions(Address address, uint limit = 10, ulong? lt = null, string hash = null, ulong? to_lt = null, bool? archival = null) { + if (address is null) + throw new ArgumentException($"Address must be defined for {nameof(TonClientType.HTTP_TONWHALESAPI)} client type."); + InTransactionsBody requestBody = new InTransactionsBody() { address = address.ToString(AddressType.Base64, new AddressStringifyOptions(true, false, false)), diff --git a/TonSdk.Client/src/LiteClientApi/LiteClientApi.cs b/TonSdk.Client/src/LiteClientApi/LiteClientApi.cs index 85e0745..3b39955 100644 --- a/TonSdk.Client/src/LiteClientApi/LiteClientApi.cs +++ b/TonSdk.Client/src/LiteClientApi/LiteClientApi.cs @@ -340,6 +340,9 @@ internal async Task GetTransactions(Address add { try { + if (address is null) + throw new ArgumentException($"Address must be defined for {nameof(TonClientType.LITECLIENT)} client type."); + var result = new List(); await Init(); diff --git a/TonSdk.Client/src/Models/Models.cs b/TonSdk.Client/src/Models/Models.cs index bad3d40..f02b4bd 100644 --- a/TonSdk.Client/src/Models/Models.cs +++ b/TonSdk.Client/src/Models/Models.cs @@ -15,6 +15,12 @@ public enum TonClientType LITECLIENT, } + + public enum SortDirection + { + ASC, + DESC + } public interface ITonClientOptions {} diff --git a/TonSdk.Client/src/Models/Transformers.cs b/TonSdk.Client/src/Models/Transformers.cs index 1ea9e66..3455d5b 100644 --- a/TonSdk.Client/src/Models/Transformers.cs +++ b/TonSdk.Client/src/Models/Transformers.cs @@ -456,7 +456,7 @@ internal struct OutRawMessage [JsonProperty("value")] public string Value; [JsonProperty("fwd_fee")] public string FwdFee; [JsonProperty("ihr_fee")] public string IhrFee; - [JsonProperty("created_lt")] public ulong CreaterLt; + [JsonProperty("created_lt")] public ulong? CreaterLt; [JsonProperty("body_hash")] public string BodyHash; [JsonProperty("msg_data")] public OutRawMessageData MsgData; [JsonProperty("message")] public string Message; @@ -471,7 +471,7 @@ internal struct OutV3RawMessage [JsonProperty("opcode")] public string OpCode; [JsonProperty("fwd_fee")] public string FwdFee; [JsonProperty("ihr_fee")] public string IhrFee; - [JsonProperty("created_lt")] public ulong CreatedLt; + [JsonProperty("created_lt")] public ulong? CreatedLt; [JsonProperty("message_content")] public OutV3RawMessageData MsgData; } @@ -852,7 +852,7 @@ public struct RawMessage public Coins Value; public Coins FwdFee; public Coins IhrFee; - public ulong CreatedLt; + public ulong? CreatedLt; public string OpCode; public string BodyHash; public RawMessageData MsgData; diff --git a/TonSdk.Client/test/LiteClientApi.test.cs b/TonSdk.Client/test/LiteClientApi.test.cs index fd534a9..7cac12a 100644 --- a/TonSdk.Client/test/LiteClientApi.test.cs +++ b/TonSdk.Client/test/LiteClientApi.test.cs @@ -64,7 +64,7 @@ public async Task Test_GetBlockTransactions() [Test] public async Task Test_GetTransactions() { - var result = await _client.GetTransactions(new Address("EQCwHyzOrKP1lBHbvMrFHChifc1TLgeJVpKgHpL9sluHU-gV"), 10, 20075201000003, "KC2THpE1CsLKCUJQj/CVtzZ1gTPt/Ho36h8bwIlcyII="); + var result = await _client.GetTransactions(address: new Address("EQCwHyzOrKP1lBHbvMrFHChifc1TLgeJVpKgHpL9sluHU-gV"), limit: 10, lt: 20075201000003, hash: "KC2THpE1CsLKCUJQj/CVtzZ1gTPt/Ho36h8bwIlcyII="); Console.WriteLine(JsonConvert.SerializeObject(result)); }