Skip to content

Commit d882f9c

Browse files
Apply a timeshift from the server when initializing IntentSender to better resolve time out of sync error (#219)
1 parent 31eb2ac commit d882f9c

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed

Assets/SequenceSDK/WaaS/Tests/IntentSenderTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ public async Task<T2> SendRequest<T, T2>(string path, T args, Dictionary<string,
164164
string responseJson = JsonConvert.SerializeObject(response);
165165
return JsonConvert.DeserializeObject<T2>(responseJson);
166166
}
167+
168+
public async Task<TimeSpan> GetTimeShift()
169+
{
170+
return TimeSpan.Zero;
171+
}
167172
}
168173

169174
private class MockHttpClientReturnsUnknownCode : IHttpClient
@@ -177,6 +182,11 @@ public async Task<T2> SendRequest<T, T2>(string path, T args, Dictionary<string,
177182
string responseJson = JsonConvert.SerializeObject(response);
178183
return JsonConvert.DeserializeObject<T2>(responseJson);
179184
}
185+
186+
public async Task<TimeSpan> GetTimeShift()
187+
{
188+
return TimeSpan.Zero;
189+
}
180190
}
181191

182192
private class MockHttpClientReturnsSuccessfulTransaction : IHttpClient
@@ -190,6 +200,11 @@ public async Task<T2> SendRequest<T, T2>(string path, T args, Dictionary<string,
190200
string responseJson = JsonConvert.SerializeObject(response);
191201
return JsonConvert.DeserializeObject<T2>(responseJson);
192202
}
203+
204+
public async Task<TimeSpan> GetTimeShift()
205+
{
206+
return TimeSpan.Zero;
207+
}
193208
}
194209

195210
[Serializable]

Packages/Sequence-Unity/Sequence/SequenceSDK/EmbeddedWallet/DataTypes/ParameterTypes/IntentPayload.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ namespace Sequence.EmbeddedWallet
1111
public class IntentPayload
1212
{
1313
public JObject data;
14-
public uint expiresAt;
15-
public uint issuedAt;
14+
public ulong expiresAt;
15+
public ulong issuedAt;
1616
public string name;
1717
public Signature[] signatures;
1818
public string version;
1919

2020
[Preserve]
2121
[JsonConstructor]
22-
public IntentPayload(string version, string name, uint expiresAt, uint issuedAt, JObject data, Signature[] signatures)
22+
public IntentPayload(string version, string name, ulong expiresAt, ulong issuedAt, JObject data, Signature[] signatures)
2323
{
2424
this.version = version;
2525
this.name = name;
@@ -29,7 +29,7 @@ public IntentPayload(string version, string name, uint expiresAt, uint issuedAt,
2929
this.signatures = signatures;
3030
}
3131

32-
public IntentPayload(string version, IntentType name, uint expiresAt, uint issuedAt, JObject data, Signature[] signatures)
32+
public IntentPayload(string version, IntentType name, ulong expiresAt, ulong issuedAt, JObject data, Signature[] signatures)
3333
{
3434
this.version = version;
3535
this.name = IntentNames[name];
@@ -39,7 +39,7 @@ public IntentPayload(string version, IntentType name, uint expiresAt, uint issue
3939
this.signatures = signatures;
4040
}
4141

42-
public IntentPayload(string version, IntentType type, JObject data, Signature[] signatures, uint timeBeforeExpiryInSeconds = 30, uint currentTime = 0)
42+
public IntentPayload(string version, IntentType type, JObject data, Signature[] signatures, uint timeBeforeExpiryInSeconds = 30, ulong currentTime = 0)
4343
{
4444
this.version = version;
4545
this.name = IntentNames[type];

Packages/Sequence-Unity/Sequence/SequenceSDK/EmbeddedWallet/HttpClient.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,30 @@ public async Task<T2> SendRequest<T, T2>(string path, T args, [CanBeNull] Dictio
238238
}
239239
}
240240

241+
public async Task<TimeSpan> GetTimeShift()
242+
{
243+
UnityWebRequest request = UnityWebRequest.Get(_waasUrl.AppendTrailingSlashIfNeeded() + "status");
244+
request.method = UnityWebRequest.kHttpVerbGET;
245+
246+
try
247+
{
248+
await request.SendWebRequest();
249+
DateTime serverTime = DateTime.Parse(request.GetResponseHeader("date")).ToUniversalTime();
250+
DateTime localTime = DateTime.UtcNow;
251+
TimeSpan timeShift = serverTime - localTime;
252+
return timeShift;
253+
}
254+
catch (Exception e)
255+
{
256+
Debug.LogError("Error getting time shift: " + e.Message);
257+
return TimeSpan.Zero;
258+
}
259+
finally
260+
{
261+
request.Dispose();
262+
}
263+
}
264+
241265
private string GetRequestErrorIfAvailable(UnityWebRequest request)
242266
{
243267
if (request.downloadHandler != null && request.downloadHandler.data != null)

Packages/Sequence-Unity/Sequence/SequenceSDK/EmbeddedWallet/IHttpClient.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Threading.Tasks;
34
using JetBrains.Annotations;
@@ -8,5 +9,7 @@ public interface IHttpClient
89
{
910
public Task<T2> SendRequest<T, T2>(string path, T args,
1011
[CanBeNull] Dictionary<string, string> headers = null, string overrideUrl = null);
12+
13+
public Task<TimeSpan> GetTimeShift();
1114
}
1215
}

Packages/Sequence-Unity/Sequence/SequenceSDK/EmbeddedWallet/IntentSender.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class IntentSender : IIntentSender
1919
private int _waasProjectId;
2020
private string _waasVersion;
2121
private string _sessionId;
22+
private TimeSpan _timeshift;
23+
private bool _ready = false;
2224

2325
private JsonSerializerSettings serializerSettings = new JsonSerializerSettings
2426
{
@@ -33,6 +35,13 @@ public IntentSender(IHttpClient httpClient, Sequence.Wallet.IWallet sessionWalle
3335
_waasProjectId = waasProjectId;
3436
_waasVersion = waasVersion;
3537
_sessionId = IntentDataOpenSession.CreateSessionId(_sessionWallet.GetAddress());
38+
GetTimeShift().ConfigureAwait(false);
39+
}
40+
41+
private async Task GetTimeShift()
42+
{
43+
_timeshift = await _httpClient.GetTimeShift();
44+
_ready = true;
3645
}
3746

3847
public async Task<T> SendIntent<T, T2>(T2 args, IntentType type, uint timeBeforeExpiryInSeconds = 30, uint currentTime = 0)
@@ -68,11 +77,11 @@ public async Task<T> SendIntent<T, T2>(T2 args, IntentType type, uint timeBefore
6877
long currentTimeAccordingToIntent = 0;
6978
if (intentPayload is IntentPayload intent)
7079
{
71-
currentTimeAccordingToIntent = intent.issuedAt;
80+
currentTimeAccordingToIntent = (long)intent.issuedAt;
7281
}
7382
else if (intentPayload is RegisterSessionIntent registerSessionIntent)
7483
{
75-
currentTimeAccordingToIntent = registerSessionIntent.intent.issuedAt;
84+
currentTimeAccordingToIntent = (long)registerSessionIntent.intent.issuedAt;
7685
}
7786
else
7887
{
@@ -116,8 +125,17 @@ private string AssemblePayloadJson<T>(T args)
116125
return JsonConvert.SerializeObject(args, serializerSettings);
117126
}
118127

119-
private async Task<object> AssembleIntentPayload(string payload, IntentType type, uint timeToLiveInSeconds, uint currentTime)
128+
private async Task<object> AssembleIntentPayload(string payload, IntentType type, uint timeToLiveInSeconds, ulong currentTime)
120129
{
130+
while (!_ready)
131+
{
132+
await Task.Yield();
133+
}
134+
135+
if (currentTime == 0)
136+
{
137+
currentTime = (ulong)DateTimeOffset.UtcNow.Add(_timeshift).ToUnixTimeSeconds();
138+
}
121139
JObject packet = JsonConvert.DeserializeObject<JObject>(payload);
122140
IntentPayload toSign = new IntentPayload(_waasVersion, type, packet, null, timeToLiveInSeconds, currentTime);
123141
string toSignJson = JsonConvert.SerializeObject(toSign, serializerSettings);

0 commit comments

Comments
 (0)