Skip to content

Commit

Permalink
Analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
skibitsky committed Aug 23, 2024
1 parent 84c033e commit ac24fe6
Show file tree
Hide file tree
Showing 20 changed files with 395 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ protected virtual void OnAccountConnected(AccountConnectedEventArgs e)
protected virtual void OnAccountDisconnected(AccountDisconnectedEventArgs e)
{
AccountDisconnected?.Invoke(this, e);

Web3Modal.EventsController.SendEvent(new Event
{
name = "DISCONNECT_SUCCESS"
});
}

protected virtual void OnAccountChanged(AccountChangedEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ private void OnSessionConnectionErrored(object sender, Exception e)
{
Web3Modal.NotificationController.Notify(NotificationType.Error, e.Message);
RefreshConnection();

Web3Modal.EventsController.SendEvent(new Event
{
name = "CONNECT_ERROR",
properties = new System.Collections.Generic.Dictionary<string, object>
{
{ "message", e.Message }
}
});
}

private IEnumerator RefreshOnIntervalRoutine()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,18 @@ protected override ConnectionProposal ConnectCore()

protected override async Task DisconnectAsyncCore()
{
await WalletConnectInstance.DisconnectAsync();
try
{
await WalletConnectInstance.DisconnectAsync();
}
catch (Exception)
{
Web3Modal.EventsController.SendEvent(new Event
{
name = "DISCONNECT_ERROR"
});
throw;
}
}

protected override async Task ChangeActiveChainAsyncCore(Chain chain)
Expand Down Expand Up @@ -154,15 +165,15 @@ protected override Task<Account[]> GetAccountsCore()
var ciapAddresses = WalletConnectInstance.SignClient.AddressProvider.AllAddresses();
return Task.FromResult(ciapAddresses.Select(ciapAddress => new Account(ciapAddress.Address, ciapAddress.ChainId)).ToArray());
}

private Account GetCurrentAccount()
{
var ciapAddress = WalletConnectInstance.SignClient.AddressProvider.CurrentAddress();
return new Account(ciapAddress.Address, ciapAddress.ChainId);
}

private static bool ActiveSessionSupportsMethod(string method)
{
{
var @namespace = WalletConnectInstance.SignClient.AddressProvider.DefaultNamespace;
var activeSession = WalletConnectInstance.ActiveSession;
return activeSession.Namespaces[@namespace].Methods.Contains(method);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine.Networking;
using WalletConnect.Web3Modal.Http;
Expand All @@ -12,18 +13,19 @@ public class ApiController
{
private const string BasePath = "https://api.web3modal.com/";
private const int TimoutSeconds = 5;

private readonly string _includedWalletIdsString = Web3Modal.Config.includedWalletIds is { Length: > 0 }
? string.Join(",", Web3Modal.Config.includedWalletIds)
: null;

private readonly string _excludedWalletIdsString = Web3Modal.Config.excludedWalletIds is { Length: > 0 }
? string.Join(",", Web3Modal.Config.excludedWalletIds)
: null;

private readonly UnityHttpClient _httpClient = new(new Uri(BasePath), TimeSpan.FromSeconds(TimoutSeconds),
new Web3ModalApiHeaderDecorator()
);

private const string Platform =
#if UNITY_ANDROID
"android";
Expand All @@ -44,13 +46,24 @@ public async Task<GetWalletsResponse> GetWallets(int page, int count, string sea

return await _httpClient.GetAsync<GetWalletsResponse>("getWallets", new Dictionary<string, string>()
{
{"page", page.ToString()},
{"entries", count.ToString()},
{"search", search},
{"platform", Platform},
{"include", _includedWalletIdsString},
{"exclude", _excludedWalletIdsString}
{ "page", page.ToString() },
{ "entries", count.ToString() },
{ "search", search },
{ "platform", Platform },
{ "include", _includedWalletIdsString },
{ "exclude", _excludedWalletIdsString }
});
}

public async Task<ApiGetAnalyticsConfigResponse> GetAnalyticsConfigAsync()
{
return await _httpClient.GetAsync<ApiGetAnalyticsConfigResponse>("getAnalyticsConfig");
}
}

public class ApiGetAnalyticsConfigResponse
{
public bool isAnalyticsEnabled { get; set; }
public bool isAppKitAuthEnabled { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using WalletConnect.Web3Modal.Http;
using WalletConnectUnity.Core;

namespace WalletConnect.Web3Modal
{
public class EventsController
{
private const string BasePath = "https://pulse.walletconnect.org/";
private const int TimoutSeconds = 5;

private readonly UnityHttpClient _httpClient = new(new Uri(BasePath), TimeSpan.FromSeconds(TimoutSeconds), new Web3ModalApiHeaderDecorator());

// private Queue<Event> _eventsQueue = new();
private AnalyticsState _state = AnalyticsState.Loading;

public async Task InitializeAsync(Web3ModalConfig config, ApiController apiController)
{
#if UNITY_WEBGL && !UNITY_EDITOR
return;
#endif

if (!Web3Modal.Config.enableAnalytics)
{
_state = AnalyticsState.Disabled;
return;
}

await LoadRemoteAnalyticsConfig(apiController);
}


private async Task LoadRemoteAnalyticsConfig(ApiController apiController)
{
try
{
var response = await apiController.GetAnalyticsConfigAsync();

_state = response.isAnalyticsEnabled
? AnalyticsState.Enabled
: AnalyticsState.Disabled;
}
catch (Exception e)
{
Debug.LogException(e);
_state = AnalyticsState.Disabled;
}
}

public async void SendEvent(Event @event)
{
try
{
if (_state == AnalyticsState.Disabled)
return;

var request = new EventRequest
{
eventId = Guid.NewGuid().ToString(),
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
bundleId = Application.identifier,
props = @event
};

var requestJson = JsonConvert.SerializeObject(request);

Debug.Log($"[EventsController] Sending event: {@event.name}");

await _httpClient.PostAsync("e", requestJson);
}
catch (Exception e)
{
Debug.LogException(e);
}
}

private enum AnalyticsState
{
Loading,
Enabled,
Disabled
}
}

[Serializable]
internal struct EventRequest
{
public string eventId;
public long timestamp;
public string bundleId;
public Event props;
}

[Serializable]
public struct Event
{
[JsonProperty("type")]
public const string type = "track";

[JsonProperty("event")]
public string name;

[JsonProperty("properties")]
public IDictionary<string, object> properties;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
Expand All @@ -17,7 +18,7 @@ public class ModalControllerUtk : ModalController

public Modal Modal { get; private set; }

public VisualElement Web3Modal { get; private set; }
public VisualElement Web3ModalElement { get; private set; }

public RouterController RouterController { get; private set; }

Expand All @@ -28,12 +29,12 @@ public class ModalControllerUtk : ModalController

protected override Task InitializeAsyncCore()
{
var web3Modal = WalletConnect.Web3Modal.Web3Modal.Instance;
var web3Modal = Web3Modal.Instance;
UIDocument = web3Modal.GetComponentInChildren<UIDocument>(true);

Web3Modal = UIDocument.rootVisualElement.Children().First();
Web3ModalElement = UIDocument.rootVisualElement.Children().First();

Modal = Web3Modal.Q<Modal>();
Modal = Web3ModalElement.Q<Modal>();

RouterController = new RouterController(Modal.body);
RouterController.ViewChanged += ViewChangedHandler;
Expand All @@ -55,18 +56,36 @@ private void ViewChangedHandler(object _, ViewChangedEventArgs args)

protected override void OpenCore(ViewType view)
{
Web3Modal.visible = true;
Web3ModalElement.visible = true;
RouterController.OpenView(view);
WCLoadingAnimator.Instance.ResumeAnimation();
OnOpenStateChanged(_openStateChangedEventArgsTrueOnOpen);

Web3Modal.EventsController.SendEvent(new Event
{
name = "MODAL_OPEN",
properties = new Dictionary<string, object>
{
{ "connected", Web3Modal.IsAccountConnected }
}
});
}

protected override void CloseCore()
{
Web3Modal.visible = false;
Web3ModalElement.visible = false;
WCLoadingAnimator.Instance.PauseAnimation();
RouterController.CloseAllViews();
OnOpenStateChanged(_openStateChangedEventArgsTrueOnClose);

Web3Modal.EventsController.SendEvent(new Event
{
name = "MODAL_CLOSE",
properties = new Dictionary<string, object>
{
{ "connected", Web3Modal.IsAccountConnected }
}
});
}

private void TickHandler()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ protected override async Task ChangeActiveChainAsyncCore(Chain chain)
await Web3Modal.ConnectorController.ChangeActiveChainAsync(chain);
else
ActiveChain = chain;

Web3Modal.EventsController.SendEvent(new Event
{
name = "SWITCH_NETWORK",
properties = new Dictionary<string, object>
{
{ "network", chain.ChainId }
}
});
}

protected override void ConnectorChainChangedHandlerCore(object sender, Connector.ChainChangedEventArgs e)
Expand All @@ -43,7 +52,7 @@ protected override async void ConnectorAccountConnectedHandlerCore(object sender
if (ActiveChain == null)
{
var defaultAccount = await e.GetAccount();

if (Chains.TryGetValue(defaultAccount.ChainId, out var defaultAccountChain))
{
ActiveChain = defaultAccountChain;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public class UnityHttpClient : HttpClientDecorator
public UnityHttpClient(params HttpClientDecorator[] decorators) : this(null, TimeSpan.FromSeconds(5), decorators)
{
}

public UnityHttpClient(Uri basePath, TimeSpan timeout, params HttpClientDecorator[] decorators)
{
_basePath = basePath;
Expand All @@ -117,6 +117,14 @@ private Task<HttpResponseContext> InvokeRecursive(HttpRequestContext context, Ca
.SendAsync(context, cancellationToken, _next);
}

public async Task PostAsync(string path, string value, IDictionary<string, string> parameters = null, IDictionary<string, string> headers = null)
{
path = path.AppendQueryString(parameters);

var request = new HttpRequestContext(path, "POST", value, "application/json", headers, _decorators);
await InvokeRecursive(request, CancellationToken.None);
}

public async Task<T> PostAsync<T>(string path, string value, IDictionary<string, string> parameters = null, IDictionary<string, string> headers = null)
{
path = path.AppendQueryString(parameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ protected virtual async void OnDisconnectButtonClick()
protected virtual void OnNetworkButtonClick()
{
Router.OpenView(ViewType.NetworkSearch);

Web3Modal.EventsController.SendEvent(new Event
{
name = "CLICK_NETWORKS"
});
}

protected virtual void OnBlockExplorerButtonClick()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace WalletConnect.Web3Modal
public class ConnectPresenter : Presenter<VisualElement>
{
private bool _disposed;

public override string Title
{
get => "Connect wallet";
Expand Down Expand Up @@ -143,7 +143,14 @@ protected virtual ListItem BuildWalletConnectListItem()

protected virtual ListItem BuildAllWalletsListItem(int responseCount)
{
var allWalletsListItem = new ListItem("All wallets", (Sprite)null, () => Router.OpenView(ViewType.WalletSearch));
var allWalletsListItem = new ListItem("All wallets", (Sprite)null, () =>
{
Router.OpenView(ViewType.WalletSearch);
Web3Modal.EventsController.SendEvent(new Event
{
name = "CLICK_ALL_WALLETS"
});
});
var roundedCount = MathF.Round((float)responseCount / 10) * 10;
allWalletsListItem.RightSlot.Add(new Tag($"{roundedCount}+", Tag.TagType.Info));
return allWalletsListItem;
Expand Down
Loading

0 comments on commit ac24fe6

Please sign in to comment.