Skip to content

Commit 5399a41

Browse files
authored
Merge pull request #25 from WalletConnect/feature/analytics
feat: analytics
2 parents fe6a14c + 39c28d4 commit 5399a41

28 files changed

Lines changed: 438 additions & 136 deletions

Packages/com.walletconnect.web3modal/Plugins/Web3Modal.jslib

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ mergeInto(LibraryManager.library, {
6767
const chains = parameters.chains;
6868

6969
const enableOnramp = parameters.enableOnramp;
70+
const enableAnalytics = parameters.enableAnalytics;
7071

7172
// Load the scripts and initialize the configuration
72-
import("https://cdn.jsdelivr.net/npm/@web3modal/cdn@5.0.11/dist/wagmi.js").then(CDNW3M => {
73+
import("https://cdn.jsdelivr.net/npm/@web3modal/cdn@5.1.2/dist/wagmi.js").then(CDNW3M => {
7374
const WagmiCore = CDNW3M['WagmiCore'];
7475
const Chains = CDNW3M['Chains'];
7576
const Web3modal = CDNW3M['Web3modal'];
@@ -107,6 +108,7 @@ mergeInto(LibraryManager.library, {
107108
wagmiConfig: config,
108109
projectId,
109110
enableOnramp: enableOnramp,
111+
enableAnalytics: enableAnalytics,
110112
disableAppend: true,
111113
});
112114

Packages/com.walletconnect.web3modal/Runtime/Connectors/Connector.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ protected virtual void OnAccountConnected(AccountConnectedEventArgs e)
122122
protected virtual void OnAccountDisconnected(AccountDisconnectedEventArgs e)
123123
{
124124
AccountDisconnected?.Invoke(this, e);
125+
126+
Web3Modal.EventsController.SendEvent(new Event
127+
{
128+
name = "DISCONNECT_SUCCESS"
129+
});
125130
}
126131

127132
protected virtual void OnAccountChanged(AccountChangedEventArgs e)

Packages/com.walletconnect.web3modal/Runtime/Connectors/WalletConnect/WalletConnectConnectionProposal.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ private void OnSessionConnectionErrored(object sender, Exception e)
3434
{
3535
Web3Modal.NotificationController.Notify(NotificationType.Error, e.Message);
3636
RefreshConnection();
37+
38+
Web3Modal.EventsController.SendEvent(new Event
39+
{
40+
name = "CONNECT_ERROR",
41+
properties = new System.Collections.Generic.Dictionary<string, object>
42+
{
43+
{ "message", e.Message }
44+
}
45+
});
3746
}
3847

3948
private IEnumerator RefreshOnIntervalRoutine()

Packages/com.walletconnect.web3modal/Runtime/Connectors/WalletConnect/WalletConnectConnector.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,18 @@ protected override ConnectionProposal ConnectCore()
123123

124124
protected override async Task DisconnectAsyncCore()
125125
{
126-
await WalletConnectInstance.DisconnectAsync();
126+
try
127+
{
128+
await WalletConnectInstance.DisconnectAsync();
129+
}
130+
catch (Exception)
131+
{
132+
Web3Modal.EventsController.SendEvent(new Event
133+
{
134+
name = "DISCONNECT_ERROR"
135+
});
136+
throw;
137+
}
127138
}
128139

129140
protected override async Task ChangeActiveChainAsyncCore(Chain chain)
@@ -154,15 +165,15 @@ protected override Task<Account[]> GetAccountsCore()
154165
var ciapAddresses = WalletConnectInstance.SignClient.AddressProvider.AllAddresses();
155166
return Task.FromResult(ciapAddresses.Select(ciapAddress => new Account(ciapAddress.Address, ciapAddress.ChainId)).ToArray());
156167
}
157-
168+
158169
private Account GetCurrentAccount()
159170
{
160171
var ciapAddress = WalletConnectInstance.SignClient.AddressProvider.CurrentAddress();
161172
return new Account(ciapAddress.Address, ciapAddress.ChainId);
162173
}
163174

164175
private static bool ActiveSessionSupportsMethod(string method)
165-
{
176+
{
166177
var @namespace = WalletConnectInstance.SignClient.AddressProvider.DefaultNamespace;
167178
var activeSession = WalletConnectInstance.ActiveSession;
168179
return activeSession.Namespaces[@namespace].Methods.Contains(method);

Packages/com.walletconnect.web3modal/Runtime/Connectors/WebGl/WebGlConnector.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ namespace WalletConnect.Web3Modal
1515
#if UNITY_WEBGL
1616
public class WebGlConnector : Connector
1717
{
18-
1918
[DllImport("__Internal")]
2019
private static extern void Initialize(string parameters, Action callback);
2120

2221
private static TaskCompletionSource<bool> _initializationTaskCompletionSource;
23-
22+
2423
private string _lastAccountStatus;
2524

2625
public WebGlConnector()
@@ -36,28 +35,29 @@ protected override async Task InitializeAsyncCore(Web3ModalConfig web3ModalConfi
3635
.Where(c => !string.IsNullOrWhiteSpace(c.ViemName))
3736
.Select(c => c.ViemName)
3837
.ToArray();
39-
38+
4039
var parameters = new WebGlInitializeParameters
4140
{
4241
projectId = walletConnectConfig.Id,
4342
metadata = walletConnectConfig.Metadata,
4443
chains = viemChainNames,
4544
enableOnramp = web3ModalConfig.enableOnramp,
45+
enableAnalytics = web3ModalConfig.enableAnalytics
4646
};
47-
47+
4848
var parametersJson = JsonConvert.SerializeObject(parameters);
49-
49+
5050
#pragma warning disable S2696
5151
_initializationTaskCompletionSource = new TaskCompletionSource<bool>();
5252
#pragma warning restore S2696
5353

5454
Initialize(parametersJson, InitializationCallback);
5555

5656
await _initializationTaskCompletionSource.Task;
57-
57+
5858
WagmiInterop.InitializeEvents();
5959
ModalInterop.InitializeEvents();
60-
60+
6161
WagmiInterop.WatchAccountTriggered += WatchAccountTriggeredHandler;
6262
WagmiInterop.WatchChainIdTriggered += WatchChainIdTriggeredHandler;
6363
}
@@ -79,9 +79,9 @@ protected override async Task<bool> TryResumeSessionAsyncCore()
7979
if (getAccountResult.isConnecting)
8080
{
8181
var tcs = new TaskCompletionSource<bool>();
82-
82+
8383
WagmiInterop.WatchAccountTriggered += WagmiInteropOnWatchAccountTriggered;
84-
84+
8585
void WagmiInteropOnWatchAccountTriggered(GetAccountReturnType arg)
8686
{
8787
if (arg.isConnecting)
@@ -91,6 +91,7 @@ void WagmiInteropOnWatchAccountTriggered(GetAccountReturnType arg)
9191

9292
WagmiInterop.WatchAccountTriggered -= WagmiInteropOnWatchAccountTriggered;
9393
}
94+
9495
var result = await tcs.Task;
9596

9697
return result;
@@ -125,12 +126,12 @@ protected override async Task<Account[]> GetAccountsCore()
125126
.Select(addr => new Account(addr, chainId))
126127
.ToArray();
127128
}
128-
129+
129130
private void WatchAccountTriggeredHandler(GetAccountReturnType arg)
130131
{
131132
var previousLastAccountStatus = _lastAccountStatus;
132133
_lastAccountStatus = arg.status;
133-
134+
134135
var account = new Account(arg.address, $"eip155:{arg.chainId}");
135136

136137
if (_lastAccountStatus == "connected" && previousLastAccountStatus != "connected")
@@ -155,11 +156,11 @@ private void WatchChainIdTriggeredHandler(int ethChainId)
155156
{
156157
if (ethChainId == default)
157158
return;
158-
159+
159160
var chainId = $"eip155:{ethChainId}";
160161
OnChainChanged(new ChainChangedEventArgs(chainId));
161162
}
162-
163+
163164
[MonoPInvokeCallback(typeof(Action))]
164165
public static void InitializationCallback()
165166
{
@@ -173,8 +174,9 @@ internal class WebGlInitializeParameters
173174
public string projectId;
174175
public Metadata metadata;
175176
public string[] chains;
176-
177+
177178
public bool enableOnramp;
179+
public bool enableAnalytics;
178180
}
179181
#endif
180182
}

Packages/com.walletconnect.web3modal/Runtime/Controllers/ApiController.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Threading;
45
using System.Threading.Tasks;
56
using UnityEngine.Networking;
67
using WalletConnect.Web3Modal.Http;
@@ -12,18 +13,19 @@ public class ApiController
1213
{
1314
private const string BasePath = "https://api.web3modal.com/";
1415
private const int TimoutSeconds = 5;
15-
16+
1617
private readonly string _includedWalletIdsString = Web3Modal.Config.includedWalletIds is { Length: > 0 }
1718
? string.Join(",", Web3Modal.Config.includedWalletIds)
1819
: null;
20+
1921
private readonly string _excludedWalletIdsString = Web3Modal.Config.excludedWalletIds is { Length: > 0 }
2022
? string.Join(",", Web3Modal.Config.excludedWalletIds)
2123
: null;
2224

2325
private readonly UnityHttpClient _httpClient = new(new Uri(BasePath), TimeSpan.FromSeconds(TimoutSeconds),
2426
new Web3ModalApiHeaderDecorator()
2527
);
26-
28+
2729
private const string Platform =
2830
#if UNITY_ANDROID
2931
"android";
@@ -44,13 +46,24 @@ public async Task<GetWalletsResponse> GetWallets(int page, int count, string sea
4446

4547
return await _httpClient.GetAsync<GetWalletsResponse>("getWallets", new Dictionary<string, string>()
4648
{
47-
{"page", page.ToString()},
48-
{"entries", count.ToString()},
49-
{"search", search},
50-
{"platform", Platform},
51-
{"include", _includedWalletIdsString},
52-
{"exclude", _excludedWalletIdsString}
49+
{ "page", page.ToString() },
50+
{ "entries", count.ToString() },
51+
{ "search", search },
52+
{ "platform", Platform },
53+
{ "include", _includedWalletIdsString },
54+
{ "exclude", _excludedWalletIdsString }
5355
});
5456
}
57+
58+
public async Task<ApiGetAnalyticsConfigResponse> GetAnalyticsConfigAsync()
59+
{
60+
return await _httpClient.GetAsync<ApiGetAnalyticsConfigResponse>("getAnalyticsConfig");
61+
}
62+
}
63+
64+
public class ApiGetAnalyticsConfigResponse
65+
{
66+
public bool isAnalyticsEnabled { get; set; }
67+
public bool isAppKitAuthEnabled { get; set; }
5568
}
5669
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Newtonsoft.Json;
5+
using UnityEngine;
6+
using WalletConnect.Web3Modal.Http;
7+
using WalletConnectSharp.Common.Logging;
8+
9+
namespace WalletConnect.Web3Modal
10+
{
11+
public class EventsController
12+
{
13+
private const string BasePath = "https://pulse.walletconnect.org/";
14+
private const int TimoutSeconds = 5;
15+
16+
private readonly UnityHttpClient _httpClient = new(new Uri(BasePath), TimeSpan.FromSeconds(TimoutSeconds), new PulseApiHeaderDecorator());
17+
18+
private AnalyticsState _state = AnalyticsState.Loading;
19+
20+
public async Task InitializeAsync(Web3ModalConfig config, ApiController apiController)
21+
{
22+
#if UNITY_WEBGL && !UNITY_EDITOR
23+
_state = AnalyticsState.Disabled;
24+
return;
25+
#endif
26+
27+
if (!Web3Modal.Config.enableAnalytics)
28+
{
29+
_state = AnalyticsState.Disabled;
30+
return;
31+
}
32+
33+
await LoadRemoteAnalyticsConfig(apiController);
34+
}
35+
36+
37+
private async Task LoadRemoteAnalyticsConfig(ApiController apiController)
38+
{
39+
try
40+
{
41+
var response = await apiController.GetAnalyticsConfigAsync();
42+
43+
_state = response.isAnalyticsEnabled
44+
? AnalyticsState.Enabled
45+
: AnalyticsState.Disabled;
46+
}
47+
catch (Exception e)
48+
{
49+
Debug.LogException(e);
50+
_state = AnalyticsState.Disabled;
51+
}
52+
}
53+
54+
public async void SendEvent(Event @event)
55+
{
56+
try
57+
{
58+
if (_state == AnalyticsState.Disabled)
59+
return;
60+
61+
var request = new EventRequest
62+
{
63+
eventId = Guid.NewGuid().ToString(),
64+
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
65+
#if UNITY_ANDROID || UNITY_IOS || UNITY_VISIONOS
66+
bundleId = Application.identifier,
67+
#endif
68+
props = @event
69+
};
70+
71+
var requestJson = JsonConvert.SerializeObject(request);
72+
73+
WCLogger.Log($"[EventsController] Sending event: {@event.name}.\n\nRequest payload:\n {requestJson}");
74+
75+
await _httpClient.PostAsync("e", requestJson);
76+
}
77+
catch (Exception e)
78+
{
79+
Debug.LogException(e);
80+
}
81+
}
82+
83+
private enum AnalyticsState
84+
{
85+
Loading,
86+
Enabled,
87+
Disabled
88+
}
89+
}
90+
91+
[Serializable]
92+
internal struct EventRequest
93+
{
94+
public string eventId;
95+
public long timestamp;
96+
public string bundleId;
97+
public Event props;
98+
}
99+
100+
[Serializable]
101+
public struct Event
102+
{
103+
[JsonProperty("type")]
104+
public const string type = "track";
105+
106+
[JsonProperty("event")]
107+
public string name;
108+
109+
[JsonProperty("properties", NullValueHandling = NullValueHandling.Ignore)]
110+
public IDictionary<string, object> properties;
111+
}
112+
}

Packages/com.walletconnect.web3modal/Runtime/Controllers/EventsController.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)