Skip to content

Commit 57cfc21

Browse files
committed
Updated some logic + cleanup
1 parent 48b1896 commit 57cfc21

7 files changed

Lines changed: 105 additions & 28 deletions

File tree

Binance.Net/Binance.Net.xml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,9 @@
15921592
<member name="M:Binance.Net.Clients.SpotApi.BinanceRestClientSpotApiAccount.StartMarginUserStreamAsync(System.Threading.CancellationToken)">
15931593
<inheritdoc />
15941594
</member>
1595+
<member name="M:Binance.Net.Clients.SpotApi.BinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(System.String,System.Nullable{System.TimeSpan},System.Threading.CancellationToken)">
1596+
<inheritdoc />
1597+
</member>
15951598
<member name="M:Binance.Net.Clients.SpotApi.BinanceRestClientSpotApiAccount.KeepAliveMarginUserStreamAsync(System.String,System.Threading.CancellationToken)">
15961599
<inheritdoc />
15971600
</member>
@@ -6216,6 +6219,11 @@
62166219
Defines the source generated JSON serialization contract metadata for a given type.
62176220
</summary>
62186221
</member>
6222+
<member name="P:Binance.Net.Converters.BinanceSourceGenerationContext.BinanceListenToken">
6223+
<summary>
6224+
Defines the source generated JSON serialization contract metadata for a given type.
6225+
</summary>
6226+
</member>
62196227
<member name="P:Binance.Net.Converters.BinanceSourceGenerationContext.BinanceListResultBinanceConvertTrade">
62206228
<summary>
62216229
Defines the source generated JSON serialization contract metadata for a given type.
@@ -17241,6 +17249,17 @@
1724117249
<param name="ct">Cancellation token</param>
1724217250
<returns>Listen key</returns>
1724317251
</member>
17252+
<member name="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(System.String,System.Nullable{System.TimeSpan},System.Threading.CancellationToken)">
17253+
<summary>
17254+
Creates a listenToken for subscribing to the cross margin user data stream.
17255+
The token is valid for up to 24 hours.
17256+
<para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
17257+
</summary>
17258+
<param name="symbol">Symbol for isolated margin, null for cross margin</param>
17259+
<param name="validity">Validity of the token, max 24 hours</param>
17260+
<param name="ct">Cancellation token</param>
17261+
<returns>ListenToken and expiration time</returns>
17262+
</member>
1724417263
<member name="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceRestClientSpotApiAccount.KeepAliveMarginUserStreamAsync(System.String,System.Threading.CancellationToken)">
1724517264
<summary>
1724617265
Sends a keep alive for the current user stream listen key to keep the stream from closing. Stream auto closes after 60 minutes if no keep alive is send. 30 minute interval for keep alive is recommended.
@@ -18798,6 +18817,20 @@
1879818817
<param name="ct">Cancellation token for closing this subscription</param>
1879918818
<returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected</returns>
1880018819
</member>
18820+
<member name="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceSocketClientSpotApiAccount.SubscribeToMarginUserDataUpdatesAsync(System.String,System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Socket.BinanceStreamOrderUpdate}},System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Socket.BinanceStreamOrderList}},System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Socket.BinanceStreamPositionsUpdate}},System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Socket.BinanceStreamBalanceUpdate}},System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.BinanceStreamEvent}},System.Threading.CancellationToken)">
18821+
<summary>
18822+
Subscribes to the cross margin account update stream using a listenToken
18823+
<para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
18824+
</summary>
18825+
<param name="listenToken">The listenToken obtained from <see cref="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(System.String,System.Nullable{System.TimeSpan},System.Threading.CancellationToken)">StartMarginUserListenTokenAsync</see></param>
18826+
<param name="onOrderUpdateMessage">The event handler for whenever an order status update is received</param>
18827+
<param name="onOcoOrderUpdateMessage">The event handler for whenever an oco order status update is received</param>
18828+
<param name="onAccountPositionMessage">The event handler for whenever an account position update is received</param>
18829+
<param name="onAccountBalanceUpdate">The event handler for whenever a deposit or withdrawal has been processed and the account balance has changed</param>
18830+
<param name="onUserDataStreamTerminated">The event handler for when the User Data Stream is stopped</param>
18831+
<param name="ct">Cancellation token for closing this subscription</param>
18832+
<returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected</returns>
18833+
</member>
1880118834
<member name="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceSocketClientSpotApiAccount.SubscribeToUserRiskDataUpdatesAsync(System.String,System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Margin.BinanceMarginCallUpdate}},System.Action{CryptoExchange.Net.Objects.Sockets.DataEvent{Binance.Net.Objects.Models.Spot.Margin.BinanceLiabilityUpdate}},System.Threading.CancellationToken)">
1880218835
<summary>
1880318836
Subscribes to the risk data account update stream. Prior to using this, the <see cref="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceRestClientSpotApiAccount.StartRiskDataUserStreamAsync(System.Threading.CancellationToken)">StartRiskDataUserStreamAsync</see> method should be called to start the stream and obtaining a listen key.
@@ -18808,6 +18841,14 @@
1880818841
<param name="ct">Cancellation token for closing this subscription</param>
1880918842
<returns>A stream subscription. This stream subscription can be used to be notified when the socket is disconnected/reconnected</returns>
1881018843
</member>
18844+
<member name="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceSocketClientSpotApiAccount.RenewMarginUserDataTokenAsync(System.String,System.Threading.CancellationToken)">
18845+
<summary>
18846+
Seamlessly renew the margin user data stream listen token on the existing connection without disconnecting. Call every ~12 hours before expiry.
18847+
<para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
18848+
</summary>
18849+
<param name="newListenToken">Listen token retrieved by the <see cref="M:Binance.Net.Interfaces.Clients.SpotApi.IBinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(System.String,System.Nullable{System.TimeSpan},System.Threading.CancellationToken)">StartMarginUserListenTokenAsync</see> method</param>
18850+
<param name="ct">Cancellation token for closing this subscription</param>
18851+
</member>
1881118852
<member name="T:Binance.Net.Interfaces.Clients.SpotApi.IBinanceSocketClientSpotApiExchangeData">
1881218853
<summary>
1881318854
Binance Spot Exchange Data socket requests and subscriptions
@@ -26406,6 +26447,21 @@
2640626447
The API key
2640726448
</summary>
2640826449
</member>
26450+
<member name="T:Binance.Net.Objects.Models.Spot.BinanceListenToken">
26451+
<summary>
26452+
Listen token
26453+
</summary>
26454+
</member>
26455+
<member name="P:Binance.Net.Objects.Models.Spot.BinanceListenToken.Token">
26456+
<summary>
26457+
Token
26458+
</summary>
26459+
</member>
26460+
<member name="P:Binance.Net.Objects.Models.Spot.BinanceListenToken.ExpirationTime">
26461+
<summary>
26462+
Expiration time
26463+
</summary>
26464+
</member>
2640926465
<member name="T:Binance.Net.Objects.Models.Spot.BinanceListResult`1">
2641026466
<summary>
2641126467
List result
@@ -41244,6 +41300,12 @@
4124441300
<member name="M:Binance.Net.Objects.Sockets.Subscriptions.BinanceMarginRiskDataSubscription.DoHandleMessage(CryptoExchange.Net.Sockets.Default.SocketConnection,System.DateTime,System.String,Binance.Net.Objects.Models.BinanceCombinedStream{Binance.Net.Objects.Models.Spot.Margin.BinanceLiabilityUpdate})">
4124541301
<inheritdoc />
4124641302
</member>
41303+
<member name="M:Binance.Net.Objects.Sockets.Subscriptions.BinanceMarginUserDataSubscription.RenewTokenAsync(System.String,System.Threading.CancellationToken)">
41304+
<summary>
41305+
Seamlessly renew the listen token on the existing connection without
41306+
disconnecting. Also updates the stored token so reconnects use the new value.
41307+
</summary>
41308+
</member>
4124741309
<member name="T:Binance.Net.Objects.Sockets.Subscriptions.BinanceSpotUserDataSubscription">
4124841310
<inheritdoc />
4124941311
</member>

Binance.Net/Clients/SpotApi/BinanceRestClientSpotApiAccount.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -916,10 +916,14 @@ public async Task<WebCallResult<string>> StartMarginUserStreamAsync(Cancellation
916916

917917
#region Create a Margin listenToken
918918
/// <inheritdoc />
919-
public async Task<WebCallResult<BinanceListenToken>> StartMarginUserListenTokenAsync(CancellationToken ct = default)
919+
public async Task<WebCallResult<BinanceListenToken>> StartMarginUserListenTokenAsync(string? symbol = null, TimeSpan? validity = null, CancellationToken ct = default)
920920
{
921-
var request = _definitions.GetOrCreate(HttpMethod.Post, "sapi/v1/userListenToken", BinanceExchange.RateLimiter.SpotRestIp, 1);
922-
return await _baseClient.SendAsync<BinanceListenToken>(request, null, ct).ConfigureAwait(false);
921+
var parameters = new ParameterCollection();
922+
parameters.AddOptional("symbol", symbol);
923+
parameters.AddOptionalBoolString("isIsolated", symbol != null ? true : null);
924+
parameters.AddOptional("validity", validity == null ? null : Math.Round(validity.Value.TotalMilliseconds));
925+
var request = _definitions.GetOrCreate(HttpMethod.Post, "sapi/v1/userListenToken", BinanceExchange.RateLimiter.SpotRestUid, 1);
926+
return await _baseClient.SendAsync<BinanceListenToken>(request, parameters, ct).ConfigureAwait(false);
923927
}
924928

925929
#endregion

Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApi.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,5 +208,10 @@ internal async Task<BinanceTradeRuleResult> CheckTradeRules(string symbol, decim
208208
}
209209

210210
public override ISocketMessageHandler CreateMessageConverter(WebSocketMessageType messageType) => new BinanceSocketSpotMessageHandler();
211+
212+
internal BinanceMarginUserDataSubscription[] GetMarginUserDataSubscriptions()
213+
{
214+
return _socketConnections.Values.SelectMany(x => x.Subscriptions.OfType<BinanceMarginUserDataSubscription>()).ToArray();
215+
}
211216
}
212217
}

Binance.Net/Clients/SpotApi/BinanceSocketClientSpotApiAccount.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,6 @@ public async Task<CallResult<UpdateSubscription>> SubscribeToUserRiskDataUpdates
136136
#endregion
137137

138138
#region Margin User Data Stream
139-
/// <inheritdoc />
140-
///
141-
/// // Store last created margin subscription for renewal
142-
internal BinanceMarginUserDataSubscription? LastMarginUserDataSubscription { get; private set; }
143-
144139
public async Task<CallResult<UpdateSubscription>> SubscribeToMarginUserDataUpdatesAsync(
145140
string listenToken,
146141
Action<DataEvent<BinanceStreamOrderUpdate>>? onOrderUpdateMessage = null,
@@ -151,17 +146,23 @@ public async Task<CallResult<UpdateSubscription>> SubscribeToMarginUserDataUpdat
151146
CancellationToken ct = default)
152147
{
153148
var subscription = new BinanceMarginUserDataSubscription(_logger, _client, listenToken, onOrderUpdateMessage, onOcoOrderUpdateMessage, onAccountPositionMessage, onAccountBalanceUpdate, onUserDataStreamTerminated);
154-
LastMarginUserDataSubscription = subscription; //store here so we can renew it
155149

156150
return await _client.SubscribeInternal2Async(_client.ClientOptions.Environment.SpotSocketApiAddress.AppendPath("ws-api/v3"), subscription, ct).ConfigureAwait(false);
157151
}
158152

159153
public async Task<CallResult> RenewMarginUserDataTokenAsync(string newListenToken, CancellationToken ct = default)
160154
{
161-
if (LastMarginUserDataSubscription == null)
162-
return new CallResult(new WebError("No active margin user data subscription"));
155+
var marginSubscriptions = _client.GetMarginUserDataSubscriptions();
156+
var tasks = new List<Task<CallResult>>();
157+
foreach (var marginSubscription in marginSubscriptions)
158+
tasks.Add(marginSubscription.RenewTokenAsync(newListenToken));
159+
160+
await Task.WhenAll(tasks).ConfigureAwait(false);
161+
var error = tasks.FirstOrDefault(x => x.Result.Error != null);
162+
if (error != null)
163+
return new CallResult(error.Result.Error);
163164

164-
return await LastMarginUserDataSubscription.RenewTokenAsync(newListenToken, ct).ConfigureAwait(false);
165+
return CallResult.SuccessResult;
165166
}
166167

167168
#endregion

Binance.Net/Interfaces/Clients/SpotApi/IBinanceRestClientSpotApiAccount.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,13 @@ Task<WebCallResult<CreateIsolatedMarginAccountResult>> DisableIsolatedMarginAcco
581581
/// <summary>
582582
/// Creates a listenToken for subscribing to the cross margin user data stream.
583583
/// The token is valid for up to 24 hours.
584+
/// <para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
584585
/// </summary>
586+
/// <param name="symbol">Symbol for isolated margin, null for cross margin</param>
587+
/// <param name="validity">Validity of the token, max 24 hours</param>
585588
/// <param name="ct">Cancellation token</param>
586589
/// <returns>ListenToken and expiration time</returns>
587-
Task<WebCallResult<BinanceListenToken>> StartMarginUserListenTokenAsync(CancellationToken ct = default);
590+
Task<WebCallResult<BinanceListenToken>> StartMarginUserListenTokenAsync(string? symbol = null, TimeSpan? validity = null, CancellationToken ct = default);
588591

589592
/// <summary>
590593
/// Sends a keep alive for the current user stream listen key to keep the stream from closing. Stream auto closes after 60 minutes if no keep alive is send. 30 minute interval for keep alive is recommended.

Binance.Net/Interfaces/Clients/SpotApi/IBinanceSocketClientSpotApiAccount.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Task<CallResult<UpdateSubscription>> SubscribeToUserDataUpdatesAsync(
5757
/// Subscribes to the cross margin account update stream using a listenToken
5858
/// <para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
5959
/// </summary>
60-
/// <param name="listenToken">The listenToken obtained from StartMarginUserListenTokenAsync</param>
60+
/// <param name="listenToken">The listenToken obtained from <see cref="IBinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(string?, TimeSpan?, CancellationToken)">StartMarginUserListenTokenAsync</see></param>
6161
/// <param name="onOrderUpdateMessage">The event handler for whenever an order status update is received</param>
6262
/// <param name="onOcoOrderUpdateMessage">The event handler for whenever an oco order status update is received</param>
6363
/// <param name="onAccountPositionMessage">The event handler for whenever an account position update is received</param>
@@ -89,11 +89,11 @@ Task<CallResult<UpdateSubscription>> SubscribeToUserRiskDataUpdatesAsync(
8989
CancellationToken ct = default);
9090

9191
/// <summary>
92-
/// Seamlessly renew the margin user data stream listen token on the existing
93-
/// connection without disconnecting. Call every ~12 hours before expiry.
92+
/// Seamlessly renew the margin user data stream listen token on the existing connection without disconnecting. Call every ~12 hours before expiry.
93+
/// <para><a href="https://developers.binance.com/docs/margin_trading/trade-data-stream" /></para>
9494
/// </summary>
95-
Task<CallResult> RenewMarginUserDataTokenAsync(
96-
string newListenToken,
97-
CancellationToken ct = default);
95+
/// <param name="newListenToken">Listen token retrieved by the <see cref="IBinanceRestClientSpotApiAccount.StartMarginUserListenTokenAsync(string?, TimeSpan?, CancellationToken)">StartMarginUserListenTokenAsync</see> method</param>
96+
/// <param name="ct">Cancellation token for closing this subscription</param>
97+
Task<CallResult> RenewMarginUserDataTokenAsync(string newListenToken, CancellationToken ct = default);
9898
}
9999
}
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace Binance.Net.Objects.Models.Spot;
1+
namespace Binance.Net.Objects.Models.Spot;
82

3+
/// <summary>
4+
/// Listen token
5+
/// </summary>
96
public class BinanceListenToken
107
{
8+
/// <summary>
9+
/// Token
10+
/// </summary>
1111
[JsonPropertyName("token")]
1212
public string Token { get; set; } = string.Empty;
13-
13+
/// <summary>
14+
/// Expiration time
15+
/// </summary>
1416
[JsonPropertyName("expirationTime")]
15-
public long ExpirationTime { get; set; }
17+
public DateTime ExpirationTime { get; set; }
1618
}

0 commit comments

Comments
 (0)