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
@@ -0,0 +1,82 @@
// Copyright (c) 2025 Thirdweb. All Rights Reserved.

#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebLoginWithSiwe.h"

#include "Async/TaskGraphInterfaces.h"
#include "Blueprint/UserWidget.h"
#include "Browser/ThirdwebOAuthBrowserUserWidget.h"
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"
#include "ThirdwebLog.h"

void UAsyncTaskThirdwebLoginWithSiwe::Activate()
{
Browser->OnSiweComplete.AddDynamic(this, &ThisClass::HandleSiweComplete);
Browser->OnError.AddDynamic(this, &ThisClass::HandleFailed);
Browser->AddToViewport(10000);
Browser->Authenticate(Wallet);
}

UAsyncTaskThirdwebLoginWithSiwe* UAsyncTaskThirdwebLoginWithSiwe::LoginWithSiwe(UObject* WorldContextObject, const FInAppWalletHandle& Wallet)
{
if (!WorldContextObject)
{
return nullptr;
}
NEW_TASK
Task->Wallet = Wallet;
Task->Browser = CreateWidget<UThirdwebOAuthBrowserUserWidget>(UGameplayStatics::GetGameInstance(WorldContextObject),
UThirdwebOAuthBrowserUserWidget::StaticClass());
Task->RegisterWithGameInstance(WorldContextObject);
return Task;
}

void UAsyncTaskThirdwebLoginWithSiwe::HandleSiweComplete(const FString& Payload, const FString& Signature)
{
if (IsInGameThread())
{
Success.Broadcast(Payload, Signature);
Browser->RemoveFromParent();
SetReadyToDestroy();
}
else
{
// Retry on the GameThread.
TWeakObjectPtr<UAsyncTaskThirdwebLoginWithSiwe> WeakThis = this;
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Payload, Signature]()
{
if (WeakThis.IsValid())
{
WeakThis->HandleSiweComplete(Payload, Signature);
}
},
TStatId(),
nullptr,
ENamedThreads::GameThread);
}
}

void UAsyncTaskThirdwebLoginWithSiwe::HandleFailed(const FString& Error)
{
if (IsInGameThread())
{
Browser->RemoveFromParent();
Failed.Broadcast(Error);
SetReadyToDestroy();
}
else
{
// Retry on the GameThread.
TWeakObjectPtr<UAsyncTaskThirdwebLoginWithSiwe> WeakThis = this;
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]()
{
if (WeakThis.IsValid())
{
WeakThis->HandleFailed(Error);
}
},
TStatId(),
nullptr,
ENamedThreads::GameThread);
}
}
81 changes: 53 additions & 28 deletions Source/Thirdweb/Private/Browser/ThirdwebOAuthBrowserUserWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

#include "Browser/ThirdwebOAuthBrowserUserWidget.h"

#include "ThirdwebLog.h"
#include "ThirdwebRuntimeSettings.h"
#include "Async/TaskGraphInterfaces.h"
#include "Blueprint/WidgetTree.h"
#include "Browser/ThirdwebOAuthExternalBrowser.h"
#include "Components/Overlay.h"
#include "Components/OverlaySlot.h"
#include "Components/PanelWidget.h"
#include "ThirdwebLog.h"
#include "ThirdwebRuntimeSettings.h"

#if PLATFORM_ANDROID
#include "Android/AndroidApplication.h"
Expand Down Expand Up @@ -70,7 +71,7 @@ void UThirdwebOAuthBrowserUserWidget::BeginDestroy()
FString UThirdwebOAuthBrowserUserWidget::GetDummyUrl()
{
#if PLATFORM_ANDROID
return UThirdwebRuntimeSettings::GetAppUri();
return UThirdwebRuntimeSettings::GetAppUri();
#else
return DummyUrl;
#endif
Expand All @@ -88,8 +89,8 @@ void UThirdwebOAuthBrowserUserWidget::Authenticate(const FInAppWalletHandle& InA
TW_LOG(VeryVerbose, TEXT("OAuthBrowserUserWidget::Authenticate::Wallet Type::%s"), Wallet.GetSourceString());
if (Wallet == FInAppWalletHandle::Siwe)
{
TW_LOG(VeryVerbose, TEXT("OAuthBrowserUserWidget::Authenticate::Authenticating against SIWE"));
ExternalBrowser->Authenticate(TEXT("SIWE"));
TW_LOG(VeryVerbose, TEXT("OAuthBrowserUserWidget::Authenticate::" "Authenticating against %s"), Wallet.GetSourceString());
ExternalBrowser->Authenticate(Wallet.GetSourceString());
return;
}

Expand All @@ -102,17 +103,21 @@ void UThirdwebOAuthBrowserUserWidget::Authenticate(const FInAppWalletHandle& InA
TW_LOG(VeryVerbose, TEXT("OAuthBrowserUserWidget::Authenticate::Authenticating against %s"), *Link);

#if PLATFORM_ANDROID
if (JNIEnv *Env = FAndroidApplication::GetJavaEnv())
{
jstring JUrl = Env->NewStringUTF(TCHAR_TO_UTF8(*Link));
jclass JClass = FAndroidApplication::FindJavaClass("com/thirdweb/unrealengine/ThirdwebActivity");
static jmethodID JLaunchUrl = FJavaWrapper::FindStaticMethod(Env, JClass, "startActivity", "(Landroid/app/Activity;Ljava/lang/String;)V", false);
ThirdwebUtils::Internal::Android::CallJniStaticVoidMethod(Env, JClass, JLaunchUrl, FJavaWrapper::GameActivityThis, JUrl);
TW_LOG(Verbose, TEXT("OAuthBrowserUserWidget::Authenticate::Opening CustomTabs"));
return;
}
TW_LOG(Error, TEXT("OAuthBrowserUserWidget::Authenticate::No JNIEnv found"));
return;
if (JNIEnv *Env = FAndroidApplication::GetJavaEnv()) {
jstring JUrl = Env->NewStringUTF(TCHAR_TO_UTF8(*Link));
jclass JClass = FAndroidApplication::FindJavaClass(
"com/thirdweb/unrealengine/ThirdwebActivity");
static jmethodID JLaunchUrl = FJavaWrapper::FindStaticMethod(
Env, JClass, "startActivity",
"(Landroid/app/Activity;Ljava/lang/String;)V", false);
ThirdwebUtils::Internal::Android::CallJniStaticVoidMethod(
Env, JClass, JLaunchUrl, FJavaWrapper::GameActivityThis, JUrl);
TW_LOG(Verbose,
TEXT("OAuthBrowserUserWidget::Authenticate::Opening CustomTabs"));
return;
}
TW_LOG(Error, TEXT("OAuthBrowserUserWidget::Authenticate::No JNIEnv found"));
return;
#endif

return ExternalBrowser->Authenticate(Link);
Expand Down Expand Up @@ -156,9 +161,27 @@ void UThirdwebOAuthBrowserUserWidget::HandleAuthenticated(const FString& AuthRes
OnAuthenticated.Broadcast(AuthResult);
}

void UThirdwebOAuthBrowserUserWidget::HandleSiweComplete(const FString& Signature, const FString& Payload)
void UThirdwebOAuthBrowserUserWidget::HandleSiweComplete(const FString& Payload, const FString& Signature)
{
OnSiweComplete.Broadcast(Signature, Payload);
if (IsInGameThread())
{
OnSiweComplete.Broadcast(Payload, Signature);
}
else
{
// Dispatch to game thread
TWeakObjectPtr<UThirdwebOAuthBrowserUserWidget> WeakThis = this;
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Payload, Signature]()
{
if (WeakThis.IsValid())
{
WeakThis->OnSiweComplete.Broadcast(Payload, Signature);
}
},
TStatId(),
nullptr,
ENamedThreads::GameThread);
}
}

void UThirdwebOAuthBrowserUserWidget::HandleError(const FString& Error)
Expand All @@ -167,16 +190,18 @@ void UThirdwebOAuthBrowserUserWidget::HandleError(const FString& Error)
}

#if PLATFORM_ANDROID
void UThirdwebOAuthBrowserUserWidget::HandleDeepLink(const FString &Url)
{
TW_LOG(VeryVerbose, TEXT("UThirdwebOAuthBrowserUserWidget::HandleDeepLink::%s"), *Url);
HandleUrlChanged(Url);
void UThirdwebOAuthBrowserUserWidget::HandleDeepLink(const FString &Url) {
TW_LOG(VeryVerbose,
TEXT("UThirdwebOAuthBrowserUserWidget::HandleDeepLink::%s"), *Url);
HandleUrlChanged(Url);
}

void UThirdwebOAuthBrowserUserWidget::HandleCustomTabsDismissed(const FString &Url)
{
TW_LOG(VeryVerbose, TEXT("UThirdwebOAuthBrowserUserWidget::HandleCustomTabsDismissed::%s"), *Url);
HandleUrlChanged(Url);
void UThirdwebOAuthBrowserUserWidget::HandleCustomTabsDismissed(
const FString &Url) {
TW_LOG(VeryVerbose,
TEXT("UThirdwebOAuthBrowserUserWidget::HandleCustomTabsDismissed::%s"),
*Url);
HandleUrlChanged(Url);
}
#endif

Expand All @@ -188,7 +213,7 @@ void UThirdwebOAuthBrowserUserWidget::SetVisible(const bool bVisible)
if (bCollapseWhenBlank)
{
#if PLATFORM_IOS | PLATFORM_ANDROID
SetRenderOpacity(1.0f);
SetRenderOpacity(1.0f);
#else
SetVisibility(ESlateVisibility::Visible);
#endif
Expand All @@ -200,7 +225,7 @@ void UThirdwebOAuthBrowserUserWidget::SetVisible(const bool bVisible)
if (bCollapseWhenBlank)
{
#if PLATFORM_IOS | PLATFORM_ANDROID
SetRenderOpacity(0.01f);
SetRenderOpacity(0.01f);
#else
SetVisibility(ESlateVisibility::Collapsed);
#endif
Expand Down
Loading