Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using DCL.Audio;
using DCL.Browser;
using DCL.DebugUtilities;
using DCL.DebugUtilities.Views;
using DCL.Diagnostics;
using DCL.FeatureFlags;
using DCL.Multiplayer.Connections.DecentralandUrls;
Expand All @@ -14,11 +13,11 @@
using DCL.PluginSystem;
using DCL.SceneLoadingScreens.SplashScreen;
using DCL.Utility;
using DCL.Web3;
using DCL.Web3.Abstract;
using DCL.Web3.Accounts.Factory;
using DCL.Web3.Authenticators;
using DCL.Web3.Identities;
using DCL.WebRequests;
using DCL.WebRequests.Analytics;
using DCL.WebRequests.ChromeDevtool;
using ECS.StreamableLoading.Cache.Disk;
Expand Down Expand Up @@ -128,7 +127,7 @@ await bootstrapContainer.InitializeContainerAsync<BootstrapContainer, BootstrapS
var realmUrls = new RealmUrls(realmLaunchSettings, new RealmNamesMap(webRequestsContainer.WebRequestController), decentralandUrlsSource);

(container.Bootstrap, container.Analytics) = CreateBootstrapperAsync(debugSettings, applicationParametersParser, splashScreen, realmUrls, diskCache, partialsDiskCache, container, webRequestsContainer, container.settings, realmLaunchSettings, world, container.settings.BuildData, dclVersion, ct);
container.CompositeWeb3Provider = CreateWeb3Dependencies(sceneLoaderSettings, web3AccountFactory, identityCache, browser, container, decentralandUrlsSource, decentralandEnvironment, applicationParametersParser);
container.CompositeWeb3Provider = CreateWeb3Dependencies(sceneLoaderSettings, web3AccountFactory, identityCache, browser, container, decentralandUrlsSource, decentralandEnvironment, applicationParametersParser, webRequestsContainer.WebRequestController);

if (container.EnableAnalytics)
{
Expand Down Expand Up @@ -225,7 +224,8 @@ private static ICompositeWeb3Provider CreateWeb3Dependencies(
BootstrapContainer container,
IDecentralandUrlsSource decentralandUrlsSource,
DecentralandEnvironment dclEnvironment,
IAppArgs appArgs)
IAppArgs appArgs,
IWebRequestController webRequestController)
{
int? identityExpirationDuration = appArgs.TryGetValue(AppArgsFlags.IDENTITY_EXPIRATION_DURATION, out string? v)
? int.Parse(v!)
Expand All @@ -238,6 +238,7 @@ private static ICompositeWeb3Provider CreateWeb3Dependencies(
new HashSet<string>(sceneLoaderSettings.Web3WhitelistMethods),
new HashSet<string>(sceneLoaderSettings.Web3ReadOnlyMethods),
web3AccountFactory,
webRequestController,
identityExpirationDuration
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
using Cysharp.Threading.Tasks;
using System;

namespace DCL.Web3.Authenticators
{
/// <summary>
/// Information about a transaction that requires user confirmation
/// </summary>
public class TransactionConfirmationRequest
{
private const string ETH_SEND_TRANSACTION = "eth_sendTransaction";

public string Method { get; set; }
public int ChainId { get; set; }

public bool IsTransaction => string.Equals(Method, ETH_SEND_TRANSACTION, StringComparison.OrdinalIgnoreCase);
public string? NetworkName { get; set; }
public string? To { get; set; }
public string? Value { get; set; }
public string? Data { get; set; }
public object[]? Params { get; set; }

// Optional extra info (best-effort) for eth_sendTransaction UI
public string? EstimatedGasFeeEth { get; set; }
public string? BalanceEth { get; set; }

/// <summary>
/// If true, hides the description text in the confirmation popup.
/// Used for internal features (like Gifting) that have their own UI with description.
/// </summary>
public bool HideDescription { get; set; }

/// <summary>
/// If true, hides the transaction details panel (balance, gas fee) in the confirmation popup.
/// Used for internal features (like Gifting) that display this info in their own UI.
/// </summary>
public bool HideDetailsPanel { get; set; }
}

/// <summary>
/// Delegate for transaction confirmation callback.
/// Returns true if user confirms, false if user rejects.
Expand All @@ -55,21 +20,11 @@ public interface ICompositeWeb3Provider : IWeb3Authenticator, IEthereumApi, IDap
/// </summary>
AuthProvider CurrentProvider { get; set; }

/// <summary>
/// Event fired when the authentication method changes
/// </summary>
event Action<AuthProvider>? OnMethodChanged;

/// <summary>
/// Returns true if ThirdWeb OTP method is currently selected
/// </summary>
bool IsThirdWebOTP { get; }

/// <summary>
/// Returns true if Dapp Wallet method is currently selected
/// </summary>
bool IsDappWallet { get; }

/// <summary>
/// Sets the callback that will be invoked when a transaction requires user confirmation.
/// The callback should return true if user confirms, false if user rejects.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Cysharp.Threading.Tasks;
using DCL.FeatureFlags;
using DCL.PerformanceAndDiagnostics.Analytics;
using DCL.Prefs;
using DCL.Web3.Identities;
Expand All @@ -20,21 +21,7 @@ public class CompositeWeb3Provider : ICompositeWeb3Provider
private readonly IWeb3IdentityCache identityCache;
private readonly IAnalyticsController analytics;

private AuthProvider currentProvider = AuthProvider.Dapp;

public AuthProvider CurrentProvider
{
get => currentProvider;

set
{
if (currentProvider != value)
{
currentProvider = value;
OnMethodChanged?.Invoke(value);
}
}
}
public AuthProvider CurrentProvider { get; set; } = AuthProvider.Dapp;

// IDappVerificationHandler - delegates to dappAuth
public event Action<(int code, DateTime expiration, string requestId)>? VerificationRequired
Expand All @@ -43,13 +30,10 @@ public AuthProvider CurrentProvider
remove => dappAuth.VerificationRequired -= value;
}

public event Action<AuthProvider>? OnMethodChanged;
public bool IsThirdWebOTP => currentProvider == AuthProvider.ThirdWeb;
public bool IsDappWallet => currentProvider == AuthProvider.Dapp;
public bool IsThirdWebOTP => CurrentProvider == AuthProvider.ThirdWeb;

private IWeb3Authenticator CurrentAuthenticator => currentProvider == AuthProvider.ThirdWeb ? thirdWebAuth : dappAuth;

private IEthereumApi CurrentEthereumApi => currentProvider == AuthProvider.ThirdWeb ? thirdWebAuth : dappAuth;
private IWeb3Authenticator currentAuthenticator => CurrentProvider == AuthProvider.ThirdWeb ? thirdWebAuth : dappAuth;
private IEthereumApi currentEthereumApi => CurrentProvider == AuthProvider.ThirdWeb ? thirdWebAuth : dappAuth;

public CompositeWeb3Provider(
ThirdWebAuthenticator thirdWebAuth,
Expand All @@ -63,10 +47,17 @@ public CompositeWeb3Provider(
this.analytics = analytics ?? throw new ArgumentNullException(nameof(analytics));
}

public void Dispose()
{
thirdWebAuth.Dispose();
dappAuth.Dispose();
identityCache.Dispose();
}

// IWeb3Authenticator
public async UniTask<IWeb3Identity> LoginAsync(LoginPayload payload, CancellationToken ct)
{
IWeb3Identity identity = await CurrentAuthenticator.LoginAsync(payload, ct);
IWeb3Identity identity = await currentAuthenticator.LoginAsync(payload, ct);
identityCache.Identity = identity;
analytics.Identify(identity);
return identity;
Expand All @@ -75,7 +66,7 @@ public async UniTask<IWeb3Identity> LoginAsync(LoginPayload payload, Cancellatio
public async UniTask LogoutAsync(CancellationToken ct)
{
analytics.Identify(null);
await CurrentAuthenticator.LogoutAsync(ct);
await currentAuthenticator.LogoutAsync(ct);
identityCache.Clear();
}

Expand All @@ -92,30 +83,31 @@ public UniTask ResendOtpAsync(CancellationToken ct = default) =>

public UniTask<bool> TryAutoLoginAsync(CancellationToken ct)
{
// Temporary heuristic: if we have a stored email, assume ThirdWeb OTP flow; otherwise default to Dapp Wallet.
string email = DCLPlayerPrefs.GetString(DCLPrefKeys.LOGGEDIN_EMAIL, string.Empty);
CurrentProvider = string.IsNullOrEmpty(email) ? AuthProvider.Dapp : AuthProvider.ThirdWeb;

// Only ThirdWeb supports auto-login
return CurrentProvider == AuthProvider.ThirdWeb
? thirdWebAuth.TryAutoLoginAsync(ct)
: UniTask.FromResult(true);
if (OtpIsDisabled())
DCLPlayerPrefs.DeleteKey(DCLPrefKeys.LOGGEDIN_EMAIL, save: true);

string storedEmail = DCLPlayerPrefs.GetString(DCLPrefKeys.LOGGEDIN_EMAIL, string.Empty);

// Heuristic: if we have a stored email, assume ThirdWeb OTP flow; otherwise default to Dapp Wallet.
if (string.IsNullOrEmpty(storedEmail))
{
CurrentProvider = AuthProvider.Dapp;
return UniTask.FromResult(true);
}
else
{
CurrentProvider = AuthProvider.ThirdWeb;
return thirdWebAuth.TryAutoLoginAsync(ct);
}

bool OtpIsDisabled() => !FeaturesRegistry.Instance.IsEnabled(FeatureId.EMAIL_OTP_AUTH);
}

// IEthereumApi
public UniTask<EthApiResponse> SendAsync(EthApiRequest request, Web3RequestSource source, CancellationToken ct) =>
CurrentEthereumApi.SendAsync(request, source, ct);
currentEthereumApi.SendAsync(request, source, ct);

public void SetTransactionConfirmationCallback(TransactionConfirmationDelegate? callback)
{
public void SetTransactionConfirmationCallback(TransactionConfirmationDelegate? callback) =>
thirdWebAuth.SetTransactionConfirmationCallback(callback);
}

public void Dispose()
{
thirdWebAuth.Dispose();
dappAuth.Dispose();
identityCache.Dispose();
}
}
}
Loading
Loading