diff --git a/Content/Defaults/WBP_Thirdweb_OAuthOverlay.uasset b/Content/Defaults/WBP_Thirdweb_OAuthOverlay.uasset index 20fcf0d..0386a80 100644 Binary files a/Content/Defaults/WBP_Thirdweb_OAuthOverlay.uasset and b/Content/Defaults/WBP_Thirdweb_OAuthOverlay.uasset differ diff --git a/Content/Examples/NodeDocs/Thirdweb_AllNodes.uasset b/Content/Examples/NodeDocs/Thirdweb_AllNodes.uasset new file mode 100644 index 0000000..36f20f7 Binary files /dev/null and b/Content/Examples/NodeDocs/Thirdweb_AllNodes.uasset differ diff --git a/Content/Examples/Widgets/BP_Thirdweb_OTPVerifyModal.uasset b/Content/Examples/Widgets/BP_Thirdweb_OTPVerifyModal.uasset index 0c96eae..dbd856d 100644 Binary files a/Content/Examples/Widgets/BP_Thirdweb_OTPVerifyModal.uasset and b/Content/Examples/Widgets/BP_Thirdweb_OTPVerifyModal.uasset differ diff --git a/Content/Examples/Widgets/Components/WBP_CountryCodeComboBox.uasset b/Content/Examples/Widgets/Components/WBP_CountryCodeComboBox.uasset new file mode 100644 index 0000000..ffcb169 Binary files /dev/null and b/Content/Examples/Widgets/Components/WBP_CountryCodeComboBox.uasset differ diff --git a/Content/Examples/Widgets/Components/WBP_WalletSourceTab.uasset b/Content/Examples/Widgets/Components/WBP_WalletSourceTab.uasset new file mode 100644 index 0000000..022fa5e Binary files /dev/null and b/Content/Examples/Widgets/Components/WBP_WalletSourceTab.uasset differ diff --git a/Content/Examples/Widgets/Components/WBP_WalletSourceTabs.uasset b/Content/Examples/Widgets/Components/WBP_WalletSourceTabs.uasset new file mode 100644 index 0000000..ed127be Binary files /dev/null and b/Content/Examples/Widgets/Components/WBP_WalletSourceTabs.uasset differ diff --git a/Content/Examples/Widgets/WBP_Thirdweb_Guest.uasset b/Content/Examples/Widgets/WBP_Thirdweb_Guest.uasset index ad7bd1f..7182aa6 100644 Binary files a/Content/Examples/Widgets/WBP_Thirdweb_Guest.uasset and b/Content/Examples/Widgets/WBP_Thirdweb_Guest.uasset differ diff --git a/Content/Examples/Widgets/WBP_Thirdweb_InApp.uasset b/Content/Examples/Widgets/WBP_Thirdweb_InApp.uasset index 22b8785..aba0d99 100644 Binary files a/Content/Examples/Widgets/WBP_Thirdweb_InApp.uasset and b/Content/Examples/Widgets/WBP_Thirdweb_InApp.uasset differ diff --git a/Content/Examples/Widgets/WBP_Thirdweb_Smart.uasset b/Content/Examples/Widgets/WBP_Thirdweb_Smart.uasset index a162295..2c1ec2f 100644 Binary files a/Content/Examples/Widgets/WBP_Thirdweb_Smart.uasset and b/Content/Examples/Widgets/WBP_Thirdweb_Smart.uasset differ diff --git a/Content/Examples/Widgets/WBP_Thirdweb_UI.uasset b/Content/Examples/Widgets/WBP_Thirdweb_UI.uasset index b380e6c..3188eff 100644 Binary files a/Content/Examples/Widgets/WBP_Thirdweb_UI.uasset and b/Content/Examples/Widgets/WBP_Thirdweb_UI.uasset differ diff --git a/Content/ThirdwebMacroLibrary.uasset b/Content/ThirdwebMacroLibrary.uasset index 6a56cc1..044d8ce 100644 Binary files a/Content/ThirdwebMacroLibrary.uasset and b/Content/ThirdwebMacroLibrary.uasset differ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c55a845 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +PYTHON_EXE ?= C:\Program Files\Python311\python.exe +BUILDS_DIR ?= E:\UnrealEngine\Thirdweb\PluginBuilds +BUILD_HOST_PLATFORM ?= false +UE_VERSION ?= 5.4 +PLUGIN_VERSION ?= 1.3.0 + +# Determine the current OS in a platform-independent manner +ifeq ($(OS),Windows_NT) + SHELL := cmd.exe + TARGET_PLATFORMS ?= Win64+Android+Linux+LinuxArm64 + PATH_SEP := \\ + UE4CLI_CONFIG_DIR_BASE := %APPDATA%\ue4cli +else + UNAME_S := $(shell uname -s) + UE4CLI_CONFIG_DIR_BASE := ~/.config/ue4cli + PATH_SEP := / + ifeq ($(UNAME_S),Linux) + TARGET_PLATFORMS ?= Android+Linux+LinuxArm64 + else ifeq ($(UNAME_S),darwin) + TARGET_PLATFORMS ?= IOS+Mac+TVOS+VisionOS + endif +endif + +ifeq ($(BUILD_HOST_PLATFORM),false) + HOST_PLATFORM_FLAG := -NoHostPlatform + else + HOST_PLATFORM_FLAG := +endif + +UE4_EXE := $(PYTHON_EXE) -m ue4cli +UE4CLI_CONFIG_DIR := $(UE4CLI_CONFIG_DIR_BASE)$(PATH_SEP)$(UE_VERSION) + +.PHONY: build +build: + $(UE4_EXE) setroot $(UE_ENGINE_DIR) + $(UE4_EXE) package $(HOST_PLATFORM_FLAG) -TargetPlatforms=$(TARGET_PLATFORMS) -Package=$(BUILDS_DIR)\\$(UE_VERSION) + +.PHONY: compress +compress: + cd $(BUILDS_DIR) + pwsh -Command Compress-Archive -LiteralPath "$(BUILDS_DIR)\\$(UE_VERSION)\\Source", "$(BUILDS_DIR)\\$(UE_VERSION)\\Content", "$(BUILDS_DIR)\\$(UE_VERSION)\\Thirdweb.uplugin" -DestinationPath "$(BUILDS_DIR)\\ThirdwebSDK-$(PLUGIN_VERSION)-$(UE_VERSION).zip" -CompressionLevel Optimal \ No newline at end of file diff --git a/Scripts/BuildPlugin.bat b/Scripts/BuildPlugin.bat index a03012f..bad7316 100644 --- a/Scripts/BuildPlugin.bat +++ b/Scripts/BuildPlugin.bat @@ -1,3 +1,2 @@ @echo off -CD /D .. ue4 package -NoHostPlatform -TargetPlatforms=Win64+Android+Linux+LinuxArm64 \ No newline at end of file diff --git a/Source/ThirdParty/Android/libthirdweb.a b/Source/ThirdParty/Android/libthirdweb.a index d59e60d..265d967 100644 --- a/Source/ThirdParty/Android/libthirdweb.a +++ b/Source/ThirdParty/Android/libthirdweb.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e01bbd3d866be1ee38b9d2a685a5121433166ff3e6217cd3a9501daf5cb1c741 -size 88139448 +oid sha256:538cd402c265a7953fcd84770627944f3685ee0d5800c1f417d4d1b75cf2b046 +size 88371628 diff --git a/Source/ThirdParty/IOS/libthirdweb.a b/Source/ThirdParty/IOS/libthirdweb.a index f0d2e5c..94f87df 100644 --- a/Source/ThirdParty/IOS/libthirdweb.a +++ b/Source/ThirdParty/IOS/libthirdweb.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:147b9d574fa190f37049726141b07b51190fc9d31db7ea9b52d65b0b7b4a6d5e -size 61070584 +oid sha256:9a4c4cbe1a1914fb76188e49a7489e0b842e9c6313337186626586770b1abdd3 +size 61055976 diff --git a/Source/ThirdParty/IOS/libthirdweb.sim.a b/Source/ThirdParty/IOS/libthirdweb.sim.a index d3c44d1..94f87df 100644 --- a/Source/ThirdParty/IOS/libthirdweb.sim.a +++ b/Source/ThirdParty/IOS/libthirdweb.sim.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:920ef0f96003a52d98c7df57c1cccc63ca7b634051fcbf157de6c352faf73d06 -size 60929776 +oid sha256:9a4c4cbe1a1914fb76188e49a7489e0b842e9c6313337186626586770b1abdd3 +size 61055976 diff --git a/Source/ThirdParty/Linux/libthirdweb.a b/Source/ThirdParty/Linux/libthirdweb.a index 1de90ea..6850281 100644 --- a/Source/ThirdParty/Linux/libthirdweb.a +++ b/Source/ThirdParty/Linux/libthirdweb.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9fda3a500ad6a00d54943bfaf4cf393cba1a045babc8e1c342e60e2e54c686fb -size 93468634 +oid sha256:7709bae02297dfcdbf403ac83c69d8741aab11c85d42b625452a0d9c50379167 +size 93720460 diff --git a/Source/ThirdParty/LinuxArm64/libthirdweb.a b/Source/ThirdParty/LinuxArm64/libthirdweb.a index f0d8691..5c330bc 100644 --- a/Source/ThirdParty/LinuxArm64/libthirdweb.a +++ b/Source/ThirdParty/LinuxArm64/libthirdweb.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:180f39bb699712903d2bb1c45956a675e4d0b82ab957273a9ec7a7b4d03b6896 -size 94435570 +oid sha256:164c72c97658f2a6de841c9c91475cf7b80f83369789afdb5c92c96df7ba0043 +size 94659054 diff --git a/Source/ThirdParty/Mac/libthirdweb.a b/Source/ThirdParty/Mac/libthirdweb.a index 882dd51..47ba25a 100644 --- a/Source/ThirdParty/Mac/libthirdweb.a +++ b/Source/ThirdParty/Mac/libthirdweb.a @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b93633b9a8401b92da3d2d9f3022fdbf4b774f95b3f720d1a57d33d45ab0d6bf -size 122544136 +oid sha256:61bcba2a763230bb9cb2453ffa81a2f9057823fc6808bc9379c13f9d6b2f318a +size 122838016 diff --git a/Source/ThirdParty/Win64/libthirdweb.lib b/Source/ThirdParty/Win64/libthirdweb.lib index 56d4eaa..959f4bc 100644 --- a/Source/ThirdParty/Win64/libthirdweb.lib +++ b/Source/ThirdParty/Win64/libthirdweb.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:499e450d8a5c79255d7f2f41b059a82f003c47735affb2f76e9f470900b69348 -size 93015574 +oid sha256:a4c01a1c11c62e05e8aaaa712211fc8f47f2a0137af09620aa93b9bf4a50ea49 +size 93399980 diff --git a/Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebBase.cpp b/Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebBase.cpp new file mode 100644 index 0000000..fc13407 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebBase.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/AsyncTaskThirdwebBase.h" + +void UAsyncTaskThirdwebBase::Activate() +{ +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.cpp new file mode 100644 index 0000000..96b4eb2 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebGetLinkedAccounts::Activate() +{ + InAppWallet.GetLinkedAccounts(BIND_UOBJECT_DELEGATE(FInAppWalletHandle::FGetLinkedAccountsDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebGetLinkedAccounts* UAsyncTaskThirdwebGetLinkedAccounts::GetLinkedAccounts(UObject* WorldContextObject, const FInAppWalletHandle& Wallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->InAppWallet = Wallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebGetLinkedAccounts::HandleResponse(const TArray& LinkedAccounts) +{ + if (IsInGameThread()) + { + Success.Broadcast(LinkedAccounts, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, LinkedAccounts]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(LinkedAccounts); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebGetLinkedAccounts::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast({}, Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.cpp new file mode 100644 index 0000000..3f1e517 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebInAppSignMessage::Activate() +{ + InAppWallet.Sign(UnsignedMessage, BIND_UOBJECT_DELEGATE(FStringDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebInAppSignMessage* UAsyncTaskThirdwebInAppSignMessage::SignMessage(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FString& Message) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->InAppWallet = Wallet; + Task->UnsignedMessage = Message; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebInAppSignMessage::HandleResponse(const FString& SignedMessage) +{ + if (IsInGameThread()) + { + Success.Broadcast(SignedMessage, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, SignedMessage]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(SignedMessage); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebInAppSignMessage::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(TEXT(""), Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebLoginWithOAuth.cpp similarity index 54% rename from Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.cpp rename to Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebLoginWithOAuth.cpp index ae98d13..066cf38 100644 --- a/Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.cpp +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebLoginWithOAuth.cpp @@ -29,28 +29,58 @@ UAsyncTaskThirdwebLoginWithOAuth* UAsyncTaskThirdwebLoginWithOAuth::LoginWithOAu { return nullptr; } - UAsyncTaskThirdwebLoginWithOAuth* Task = NewObject(WorldContextObject); + NEW_TASK Task->Wallet = Wallet; Task->Browser = CreateWidget(UGameplayStatics::GetGameInstance(WorldContextObject), UThirdwebOAuthBrowserUserWidget::StaticClass()); Task->RegisterWithGameInstance(WorldContextObject); return Task; } -void UAsyncTaskThirdwebLoginWithOAuth::HandleFailed(const FString& Error) +void UAsyncTaskThirdwebLoginWithOAuth::HandleAuthenticated(const FString& AuthResult) { - Failed.Broadcast(Error); - Browser->RemoveFromParent(); - SetReadyToDestroy(); + Wallet.SignInWithOAuth(AuthResult, BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleSignedIn), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); } -void UAsyncTaskThirdwebLoginWithOAuth::HandleAuthenticated(const FString& AuthResult) +void UAsyncTaskThirdwebLoginWithOAuth::HandleSignedIn() { - if (FString Error; !Wallet.SignInWithOAuth(AuthResult, Error)) + if (IsInGameThread()) { - return HandleFailed(Error); + Success.Broadcast(TEXT("")); + Browser->RemoveFromParent(); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleSignedIn(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); } - Success.Broadcast(TEXT("")); - Browser->RemoveFromParent(); - SetReadyToDestroy(); } +void UAsyncTaskThirdwebLoginWithOAuth::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Browser->RemoveFromParent(); + Failed.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.cpp new file mode 100644 index 0000000..a9d5d35 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSendOTP::Activate() +{ + InAppWallet.SendOTP(BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebSendOTP* UAsyncTaskThirdwebSendOTP::SendOTP(UObject* WorldContextObject, const FInAppWalletHandle& Wallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->InAppWallet = Wallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebSendOTP::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebSendOTP::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.cpp new file mode 100644 index 0000000..181ef91 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebCreateAuthEndpointWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemAuthEndpointWallet(EcosystemPartnerId, BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreateAuthEndpointWallet(BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.cpp new file mode 100644 index 0000000..702ee01 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebCreateEmailWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemEmailWallet(EcosystemPartnerId, AuthInput, BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreateEmailWallet(AuthInput,BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.cpp new file mode 100644 index 0000000..b52a5a8 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebCreateGuestWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemGuestWallet(EcosystemPartnerId, BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreateGuestWallet(BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.cpp new file mode 100644 index 0000000..af98ef5 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebCreateJwtWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemJwtWallet(EcosystemPartnerId, BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreateJwtWallet(BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.cpp new file mode 100644 index 0000000..f633558 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +UAsyncTaskThirdwebCreateOAuthWallet* UAsyncTaskThirdwebCreateOAuthWallet::CreateOAuthWallet(UObject* WorldContextObject, const EThirdwebOAuthProvider Provider, const FString& PartnerId) +{ + if (!WorldContextObject) + { + return nullptr; + } + ThisClass* Task = NewObject(WorldContextObject); + Task->EcosystemPartnerId = PartnerId; + Task->Provider = Provider; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebCreateOAuthWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemOAuthWallet(EcosystemPartnerId, Provider,BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreateOAuthWallet(Provider,BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.cpp new file mode 100644 index 0000000..ae1d63b --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.h" + +#include "ThirdwebRuntimeSettings.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebCreatePhoneWallet::Activate() +{ + if (UThirdwebRuntimeSettings::IsEcosystem()) + { + return FInAppWalletHandle::CreateEcosystemPhoneWallet(EcosystemPartnerId, AuthInput,BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); + } + FInAppWalletHandle::CreatePhoneWallet(AuthInput,BIND_CREATE_WALLET_SUCCESS_DELEGATE, BIND_CREATE_WALLET_ERROR_DELEGATE); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.cpp new file mode 100644 index 0000000..47461ed --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.h" + +#include "Components/SlateWrapperTypes.h" + +#include "Wallets/ThirdwebSmartWalletHandle.h" + +UAsyncTaskThirdwebCreateSmartWallet* UAsyncTaskThirdwebCreateSmartWallet::CreateSmartWallet(UObject* WorldContextObject, + const FInAppWalletHandle& InAppWallet, + const int64 ChainID, + const bool bGasless, + const FString& Factory, + const FString& AccountOverride) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + + Task->InAppWallet = InAppWallet; + Task->ChainID = ChainID; + Task->bGasless = bGasless; + Task->Factory = Factory; + Task->AccountOverride = AccountOverride; + + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebCreateSmartWallet::Activate() +{ + FSmartWalletHandle::Create( + InAppWallet, + ChainID, + bGasless, + Factory, + AccountOverride, + BIND_UOBJECT_DELEGATE(FSmartWalletHandle::FCreateSmartWalletDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); +} + +void UAsyncTaskThirdwebCreateSmartWallet::HandleResponse(const FSmartWalletHandle& Wallet) +{ + if (IsInGameThread()) + { + Success.Broadcast(Wallet, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Wallet]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(Wallet); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebCreateSmartWallet::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(FSmartWalletHandle(), Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.cpp new file mode 100644 index 0000000..885832e --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +void UAsyncTaskThirdwebInAppCreateWalletBase::HandleResponse(const FInAppWalletHandle& Wallet) +{ + if (IsInGameThread()) + { + Success.Broadcast(Wallet, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Wallet]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(Wallet); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebInAppCreateWalletBase::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(FInAppWalletHandle(), Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.cpp new file mode 100644 index 0000000..a9dd178 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLink::Activate() +{ + switch (InAppWallet.GetSource()) + { + case FInAppWalletHandle::Email: return InAppWallet.LinkOTP( + NewInAppWallet, + AuthInput, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + case FInAppWalletHandle::Phone: return InAppWallet.LinkOTP( + NewInAppWallet, + AuthInput, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + case FInAppWalletHandle::OAuthProvider: return InAppWallet.LinkOAuth( + NewInAppWallet, + AuthInput, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + case FInAppWalletHandle::Jwt: return InAppWallet.LinkJwt( + NewInAppWallet, + AuthInput, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + case FInAppWalletHandle::Guest: return InAppWallet.LinkGuest( + NewInAppWallet, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + case FInAppWalletHandle::AuthEndpoint: return InAppWallet.LinkAuthEndpoint( + NewInAppWallet, + AuthInput, + BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); + default: return HandleFailed(TEXT("Invalid Wallet")); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.cpp new file mode 100644 index 0000000..1c118c9 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLinkAuthEndpoint::Activate() +{ + InAppWallet.LinkAuthEndpoint(NewInAppWallet, AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.cpp new file mode 100644 index 0000000..f5a6a7b --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.h" + +void UAsyncTaskThirdwebLinkBase::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebLinkBase::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.cpp new file mode 100644 index 0000000..28a766f --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLinkGuest::Activate() +{ + InAppWallet.LinkGuest(NewInAppWallet, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.cpp new file mode 100644 index 0000000..a93cbda --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLinkJwt::Activate() +{ + InAppWallet.LinkJwt(NewInAppWallet, AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.cpp new file mode 100644 index 0000000..a9220a7 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLinkOAuth::Activate() +{ + InAppWallet.LinkOAuth(NewInAppWallet, AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.cpp new file mode 100644 index 0000000..4c42cb6 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebLinkOTP::Activate() +{ + InAppWallet.LinkOTP(NewInAppWallet, AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskSignInBase.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskSignInBase.cpp new file mode 100644 index 0000000..b443586 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskSignInBase.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInBase.h" + +void UAsyncTaskThirdwebSignInBase::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebSignInBase::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.cpp new file mode 100644 index 0000000..20afbb1 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.cpp @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignIn::Activate() +{ + switch (InAppWallet.GetSource()) + { + case FInAppWalletHandle::Email: return InAppWallet.SignInWithOTP(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + case FInAppWalletHandle::Phone: return InAppWallet.SignInWithOTP(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + case FInAppWalletHandle::OAuthProvider: return InAppWallet.SignInWithOAuth(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + case FInAppWalletHandle::Jwt: return InAppWallet.SignInWithJwt(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + case FInAppWalletHandle::Guest: return InAppWallet.SignInWithGuest(BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + case FInAppWalletHandle::AuthEndpoint: return InAppWallet.SignInWithAuthEndpoint(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + default: return HandleFailed(TEXT("Invalid Wallet")); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.cpp new file mode 100644 index 0000000..43f4a08 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignInWithAuthEndpoint::Activate() +{ + InAppWallet.SignInWithAuthEndpoint(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.cpp new file mode 100644 index 0000000..2ab9493 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignInWithGuest::Activate() +{ + InAppWallet.SignInWithGuest(BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.cpp new file mode 100644 index 0000000..7eb592c --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignInWithJwt::Activate() +{ + InAppWallet.SignInWithJwt(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.cpp new file mode 100644 index 0000000..073bd07 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignInWithOAuth::Activate() +{ + InAppWallet.SignInWithOAuth(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.cpp new file mode 100644 index 0000000..007d275 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSignInWithOTP::Activate() +{ + InAppWallet.SignInWithOTP(AuthInput, BIND_UOBJECT_DELEGATE(FStreamableDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.cpp new file mode 100644 index 0000000..5e6830b --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebAddAdmin::Activate() +{ + FString Error; + SmartWallet.AddAdmin(Signer, BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebAddAdmin* UAsyncTaskThirdwebAddAdmin::AddAdmin(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->Signer = Signer; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebAddAdmin::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebAddAdmin::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.cpp new file mode 100644 index 0000000..3ee25ab --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebCreateSessionKey::Activate() +{ + SmartWallet.CreateSessionKey( + Signer, + ApprovedTargets, + NativeTokenLimitPerTransactionInWei, + PermissionStart, + PermissionEnd, + RequestValidityStart, + RequestValidityEnd, + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleResponse), + BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + ); +} + +UAsyncTaskThirdwebCreateSessionKey* UAsyncTaskThirdwebCreateSessionKey::CreateSessionKey(UObject* WorldContextObject, + const FSmartWalletHandle& Wallet, + const FString& Signer, + const TArray& ApprovedTargets, + const FString& NativeTokenLimitPerTransactionInWei, + const FDateTime& PermissionStart, + const FDateTime& PermissionEnd, + const FDateTime& RequestValidityStart, + const FDateTime& RequestValidityEnd) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + + Task->SmartWallet = Wallet; + Task->Signer = Signer; + Task->ApprovedTargets = ApprovedTargets; + Task->NativeTokenLimitPerTransactionInWei = NativeTokenLimitPerTransactionInWei; + Task->PermissionStart = PermissionStart; + Task->PermissionEnd = PermissionEnd; + Task->RequestValidityStart = RequestValidityStart; + Task->RequestValidityEnd = RequestValidityEnd; + + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebCreateSessionKey::HandleResponse(const FString& TxHash) +{ + if (IsInGameThread()) + { + Success.Broadcast(TxHash, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, TxHash]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(TxHash); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebCreateSessionKey::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(TEXT(""), Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.cpp new file mode 100644 index 0000000..8cb61e6 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebGetAdmins::Activate() +{ + SmartWallet.GetAdmins(BIND_UOBJECT_DELEGATE(FStringArrayDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebGetAdmins* UAsyncTaskThirdwebGetAdmins::GetAdmins(UObject* WorldContextObject, const FSmartWalletHandle& Wallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebGetAdmins::HandleResponse(const TArray& Admins) +{ + if (IsInGameThread()) + { + Success.Broadcast(Admins, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Admins]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(Admins); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebGetAdmins::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast({}, Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.cpp new file mode 100644 index 0000000..3f2415c --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.cpp @@ -0,0 +1,83 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebIsActiveSigner::Activate() +{ + FString Error; + SmartWallet.IsDeployed(BIND_UOBJECT_DELEGATE(FBoolDelegate, HandleIsDeployedResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebIsActiveSigner* UAsyncTaskThirdwebIsActiveSigner::IsActiveSigner(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& BackendWallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->BackendWallet = BackendWallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebIsActiveSigner::HandleIsDeployedResponse(const bool& bDeployed) +{ + if (bDeployed) + { + return SmartWallet.GetActiveSigners(BIND_UOBJECT_DELEGATE(FSmartWalletHandle::FGetActiveSignersDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + } + HandleResponse({}); +} + +void UAsyncTaskThirdwebIsActiveSigner::HandleResponse(const TArray& Signers) +{ + if (IsInGameThread()) + { + for (int i = 0; i < Signers.Num(); i++) + { + if (Signers[i].Address.Equals(BackendWallet, ESearchCase::IgnoreCase)) + { + Success.Broadcast(true, TEXT("")); + return SetReadyToDestroy(); + } + } + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Signers]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(Signers); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebIsActiveSigner::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(false, Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.cpp new file mode 100644 index 0000000..43a1be2 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebIsDeployed::Activate() +{ + FString Error; + SmartWallet.IsDeployed(BIND_UOBJECT_DELEGATE(FBoolDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebIsDeployed* UAsyncTaskThirdwebIsDeployed::IsDeployed(UObject* WorldContextObject, const FSmartWalletHandle& Wallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebIsDeployed::HandleResponse(const bool& bIsDeployed) +{ + if (IsInGameThread()) + { + if (bIsDeployed) + { + Deployed.Broadcast(TEXT("")); + } + else + { + NotDeployed.Broadcast(TEXT("")); + } + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, bIsDeployed]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(bIsDeployed); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebIsDeployed::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsGetActiveSigners.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsGetActiveSigners.cpp new file mode 100644 index 0000000..745e4bd --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsGetActiveSigners.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "ThirdwebSigner.h" + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetActiveSigners.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebGetActiveSigners::Activate() +{ + FString Error; + SmartWallet.IsDeployed(BIND_UOBJECT_DELEGATE(FBoolDelegate, HandleIsDeployedResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebGetActiveSigners* UAsyncTaskThirdwebGetActiveSigners::GetActiveSigners(UObject* WorldContextObject, const FSmartWalletHandle& Wallet) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebGetActiveSigners::HandleIsDeployedResponse(const bool& bDeployed) +{ + if (bDeployed) + { + return SmartWallet.GetActiveSigners(BIND_UOBJECT_DELEGATE(FSmartWalletHandle::FGetActiveSignersDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); + } + HandleResponse({}); +} + +void UAsyncTaskThirdwebGetActiveSigners::HandleResponse(const TArray& Signers) +{ + if (IsInGameThread()) + { + Success.Broadcast(Signers, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Signers]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(Signers); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebGetActiveSigners::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast({}, Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.cpp new file mode 100644 index 0000000..c716166 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebRemoveAdmin::Activate() +{ + FString Error; + SmartWallet.RemoveAdmin(Signer, BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebRemoveAdmin* UAsyncTaskThirdwebRemoveAdmin::RemoveAdmin(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->Signer = Signer; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebRemoveAdmin::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + return SetReadyToDestroy(); + } + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); +} + +void UAsyncTaskThirdwebRemoveAdmin::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.cpp new file mode 100644 index 0000000..c8bdc28 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.h" + +#include "ThirdwebSigner.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebRevokeSessionKey::Activate() +{ + FString Error; + SmartWallet.RevokeSessionKey(Signer, BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebRevokeSessionKey* UAsyncTaskThirdwebRevokeSessionKey::RevokeSessionKey(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->Signer = Signer; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebRevokeSessionKey::HandleResponse() +{ + if (IsInGameThread()) + { + Success.Broadcast(TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebRevokeSessionKey::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.cpp b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.cpp new file mode 100644 index 0000000..d3d7200 --- /dev/null +++ b/Source/Thirdweb/Private/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.h" + +#include "Components/SlateWrapperTypes.h" + +void UAsyncTaskThirdwebSmartSignMessage::Activate() +{ + SmartWallet.Sign(UnsignedMessage, BIND_UOBJECT_DELEGATE(FStringDelegate, HandleResponse), BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed)); +} + +UAsyncTaskThirdwebSmartSignMessage* UAsyncTaskThirdwebSmartSignMessage::SignMessage(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Message) +{ + if (!WorldContextObject) + { + return nullptr; + } + NEW_TASK + Task->SmartWallet = Wallet; + Task->UnsignedMessage = Message; + Task->RegisterWithGameInstance(WorldContextObject); + return Task; +} + +void UAsyncTaskThirdwebSmartSignMessage::HandleResponse(const FString& SignedMessage) +{ + if (IsInGameThread()) + { + Success.Broadcast(SignedMessage, TEXT("")); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, SignedMessage]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleResponse(SignedMessage); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} + +void UAsyncTaskThirdwebSmartSignMessage::HandleFailed(const FString& Error) +{ + if (IsInGameThread()) + { + Failed.Broadcast(TEXT(""), Error); + SetReadyToDestroy(); + } + else + { + // Retry on the GameThread. + TWeakObjectPtr WeakThis = this; + FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, Error]() + { + if (WeakThis.IsValid()) + { + WeakThis->HandleFailed(Error); + } + }, TStatId(), nullptr, ENamedThreads::GameThread); + } +} diff --git a/Source/Thirdweb/Private/Thirdweb.cpp b/Source/Thirdweb/Private/Thirdweb.cpp index 7c033bb..b7266c7 100644 --- a/Source/Thirdweb/Private/Thirdweb.cpp +++ b/Source/Thirdweb/Private/Thirdweb.cpp @@ -18,28 +18,6 @@ bool Thirdweb::FFIResult::AssignResult(FString& Output, const bool bErrorOnlyRes return bSuccess; } -bool Thirdweb::FFIResult::AssignRetryResult(bool& bCanRetry, FString& Output, const bool bErrorOnlyResult) const -{ - Log(); - bool bSuccess = success; - bCanRetry = false; - Output = FString(UTF8_TO_TCHAR(message)); - - if (bSuccess && Output.StartsWith("RecoverableError")) - { - bSuccess = false; - bCanRetry = true; - Output = Output.Mid(17).TrimStart(); - } - - if (bSuccess && bErrorOnlyResult) - { - Output.Empty(); - } - free_ffi_result(*this); - return bSuccess; -} - FString Thirdweb::FFIResult::GetOutput() const { Log(); diff --git a/Source/Thirdweb/Private/ThirdwebFunctionLibrary.cpp b/Source/Thirdweb/Private/ThirdwebFunctionLibrary.cpp index 96850ae..f181565 100644 --- a/Source/Thirdweb/Private/ThirdwebFunctionLibrary.cpp +++ b/Source/Thirdweb/Private/ThirdwebFunctionLibrary.cpp @@ -9,6 +9,8 @@ #include "ThirdwebSigner.h" #include "ThirdwebUtils.h" +#include "Data/ThirdwebCountryCodes.h" + #include "Wallets/ThirdwebInAppWalletHandle.h" #include "Wallets/ThirdwebSmartWalletHandle.h" #include "Wallets/ThirdwebWalletHandle.h" @@ -53,83 +55,6 @@ FText UThirdwebFunctionLibrary::Conv_SmartWalletHandleToText(FSmartWalletHandle return FText::FromString(Conv_SmartWalletHandleToString(Wallet)); } -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppEmailWallet(const FString& Email, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemEmailWallet(PartnerId, Email, Wallet, Error) - : FInAppWalletHandle::CreateEmailWallet(Email, Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppOAuthWallet(const EThirdwebOAuthProvider Provider, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemOAuthWallet(PartnerId, Provider, Wallet, Error) - : FInAppWalletHandle::CreateOAuthWallet(Provider, Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppPhoneWallet(const FString& Phone, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemPhoneWallet(PartnerId, Phone, Wallet, Error) - : FInAppWalletHandle::CreatePhoneWallet(Phone, Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppJwtWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemJwtWallet(PartnerId, Wallet, Error) - : FInAppWalletHandle::CreateJwtWallet(Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppAuthEndpointWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemAuthEndpointWallet(PartnerId, Wallet, Error) - : FInAppWalletHandle::CreateAuthEndpointWallet(Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateInAppGuestWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) -{ - return (UThirdwebRuntimeSettings::IsEcosystem() - ? FInAppWalletHandle::CreateEcosystemGuestWallet(PartnerId, Wallet, Error) - : FInAppWalletHandle::CreateGuestWallet(Wallet, Error)) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateSmartWallet(const FInAppWalletHandle PersonalWallet, - FSmartWalletHandle& SmartWallet, - FString& Error, - const int64 ChainID, - const bool bGasless, - const FString& Factory, - const FString& AccountOverride) -{ - bool bSuccessful; - FSmartWalletHandle SmartWalletHandle = FSmartWalletHandle::Create(PersonalWallet, ChainID, bGasless, Factory, AccountOverride, bSuccessful, Error); - return bSuccessful ? EFunctionResult::Success : EFunctionResult::Failed; -} - -FString UThirdwebFunctionLibrary::BP_SignInAppMessage(const FInAppWalletHandle& Wallet, const FString& Message) -{ - return Wallet.Sign(Message); -} - -FString UThirdwebFunctionLibrary::BP_SignSmartMessage(const FSmartWalletHandle& Wallet, const FString& Message) -{ - return Wallet.Sign(Message); -} - bool UThirdwebFunctionLibrary::BP_WalletIsConnected(const FInAppWalletHandle& Wallet) { return Wallet.IsConnected(); @@ -140,46 +65,12 @@ void UThirdwebFunctionLibrary::BP_DisconnectWallet(const FInAppWalletHandle& Wal return Wallet.Disconnect(); } -EOTPVerificationFunctionResult UThirdwebFunctionLibrary::BP_VerifyOTP(const EThirdwebOTPMethod Method, FInAppWalletHandle Wallet, const FString& OTP, FString& Error) -{ - bool bCanRetry = false; - if (Wallet.VerifyOTP(Method, OTP, Error)) - { - return EOTPVerificationFunctionResult::Verified; - } - return bCanRetry ? EOTPVerificationFunctionResult::Retry : EOTPVerificationFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_SendOTP(const EThirdwebOTPMethod Method, FInAppWalletHandle Wallet, FString& Error) -{ - return Wallet.SendOTP(Method, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} EFunctionResult UThirdwebFunctionLibrary::BP_FetchOAuthLoginLink(FInAppWalletHandle Wallet, const FString& RedirectUrl, FString& LoginLink, FString& Error) { return Wallet.FetchOAuthLoginURL(RedirectUrl, LoginLink, Error) ? EFunctionResult::Success : EFunctionResult::Failed; } -EFunctionResult UThirdwebFunctionLibrary::BP_SignInWithOAuth(FInAppWalletHandle Wallet, const FString& AuthResult, FString& Error) -{ - return Wallet.SignInWithOAuth(AuthResult, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_SignInWithJwt(FInAppWalletHandle Wallet, const FString& Jwt, FString& Error) -{ - return Wallet.SignInWithJwt(Jwt, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_SignInWithAuthEndpoint(FInAppWalletHandle Wallet, const FString& Payload, FString& Error) -{ - return Wallet.SignInWithAuthEndpoint(Payload, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_SignInWithGuest(FInAppWalletHandle Wallet, FString& Error) -{ - return Wallet.SignInWithGuest(Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - bool UThirdwebFunctionLibrary::BP_InAppWalletIsValid(const FInAppWalletHandle& Wallet) { return Wallet.IsValid(); @@ -190,64 +81,24 @@ bool UThirdwebFunctionLibrary::BP_SmartWalletIsValid(const FSmartWalletHandle& W return Wallet.IsValid(); } -ESmartWalletDeployedFunctionResult UThirdwebFunctionLibrary::BP_IsSmartWalletDeployed(FSmartWalletHandle Wallet, FString& Error) -{ - if (bool bDeployed; Wallet.IsDeployed(bDeployed, Error)) - { - return bDeployed ? ESmartWalletDeployedFunctionResult::Deployed : ESmartWalletDeployedFunctionResult::NotDeployed; - } - return ESmartWalletDeployedFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_CreateSmartWalletSessionKey(FSmartWalletHandle Wallet, - const FString& Signer, - const TArray& ApprovedTargets, - const FString& NativeTokenLimitPerTransactionInWei, - const FDateTime& PermissionStart, - const FDateTime& PermissionEnd, - const FDateTime& RequestValidityStart, - const FDateTime& RequestValidityEnd, - FString& TransactionHash, - FString& Error) -{ - return Wallet.CreateSessionKey(Signer, ApprovedTargets, NativeTokenLimitPerTransactionInWei, PermissionStart, PermissionEnd, RequestValidityStart, RequestValidityEnd, TransactionHash, Error) - ? EFunctionResult::Success - : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_GetSmartWalletAdmins(FSmartWalletHandle Wallet, TArray& Admins, FString& Error) -{ - return Wallet.GetAdmins(Admins, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_GetSmartWalletActiveSigners(FSmartWalletHandle Wallet, TArray& Signers, FString& Error) -{ - return Wallet.GetActiveSigners(Signers, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_RevokeSmartWalletSessionKey(FSmartWalletHandle Wallet, const FString& Signer, FString& Error) -{ - return Wallet.RevokeSessionKey(Signer, Error) ? EFunctionResult::Success : EFunctionResult::Failed; -} - -EFunctionResult UThirdwebFunctionLibrary::BP_AddSmartWalletAdmin(FSmartWalletHandle Wallet, const FString& Signer, FString& Error) +FText UThirdwebFunctionLibrary::Conv_ThirdwebOAuthProviderToText(EThirdwebOAuthProvider Provider) { - return Wallet.AddAdmin(Signer, Error) ? EFunctionResult::Success : EFunctionResult::Failed; + return ThirdwebUtils::ToText(Provider); } -EFunctionResult UThirdwebFunctionLibrary::BP_RemoveSmartWalletAdmin(FSmartWalletHandle Wallet, const FString& Signer, FString& Error) +FString UThirdwebFunctionLibrary::Conv_ThirdwebOAuthProviderToString(EThirdwebOAuthProvider Provider) { - return Wallet.RemoveAdmin(Signer, Error) ? EFunctionResult::Success : EFunctionResult::Failed; + return ThirdwebUtils::ToString(Provider); } -FText UThirdwebFunctionLibrary::Conv_ThirdwebOAuthProviderToText(EThirdwebOAuthProvider Provider) +EThirdwebOAuthProvider UThirdwebFunctionLibrary::Conv_TextToThirdwebOAuthProvider(FText Text) { - return ThirdwebUtils::ToText(Provider); + return ThirdwebUtils::ToOAuthProvider(Text); } -FString UThirdwebFunctionLibrary::Conv_ThirdwebOAuthProviderToString(EThirdwebOAuthProvider Provider) +EThirdwebOAuthProvider UThirdwebFunctionLibrary::Conv_StringToThirdwebOAuthProvider(FString String) { - return ThirdwebUtils::ToString(Provider); + return ThirdwebUtils::ToOAuthProvider(String); } bool UThirdwebFunctionLibrary::BP_IsStringValidAddress(const FString& Address, const bool bWithChecksum) @@ -265,12 +116,12 @@ FString UThirdwebFunctionLibrary::Conv_StringAddressToStringChecksummedAddress(c return ThirdwebUtils::ToChecksummedAddress(Address); } -bool UThirdwebFunctionLibrary::BP_IsTextValidAddress(const FText& Address, const bool bWithChecksum) +bool UThirdwebFunctionLibrary::BP_IsTextValidAddress(const FText Address, const bool bWithChecksum) { return !Address.IsEmpty() && ThirdwebUtils::IsValidAddress(Address.ToString(), bWithChecksum); } -bool UThirdwebFunctionLibrary::BP_IsTextChecksummedAddress(const FText& Address) +bool UThirdwebFunctionLibrary::BP_IsTextChecksummedAddress(const FText Address) { return !Address.IsEmpty() && ThirdwebUtils::IsChecksummedAddress(Address.ToString()); } @@ -280,24 +131,18 @@ FText UThirdwebFunctionLibrary::Conv_TextAddressToStringChecksummedAddress(const return Address.IsEmpty() ? FText::GetEmpty() : FText::FromString(ThirdwebUtils::ToChecksummedAddress(Address.ToString())); } -bool UThirdwebFunctionLibrary::BP_IsActiveSigner(FSmartWalletHandle Wallet, const FString& BackendWallet) +FString UThirdwebFunctionLibrary::BP_ZeroAddress() +{ + return ThirdwebUtils::ZeroAddress; +} + +FThirdwebCountryCode UThirdwebFunctionLibrary::BP_GetCountryCodeData(const int32 CountryCode) { - FString Error; - if (bool bDeployed; Wallet.IsDeployed(bDeployed, Error)) - { - if (bDeployed) - { - if (TArray Signers; Wallet.GetActiveSigners(Signers, Error)) - { - for (int i = 0; i < Signers.Num(); i++) - { - if (Signers[i].Address.Equals(BackendWallet, ESearchCase::IgnoreCase)) - { - return true; - } - } - } - } - } - return false; + return ThirdwebCountryCodes::GetCountryCodeData(CountryCode); } + +TArray UThirdwebFunctionLibrary::BP_GetAllCountryCodeData() +{ + return ThirdwebCountryCodes::GetCountryCodesArray(); +} + diff --git a/Source/Thirdweb/Private/Wallets/ThirdwebInAppWalletHandle.cpp b/Source/Thirdweb/Private/Wallets/ThirdwebInAppWalletHandle.cpp index 92ded1e..d0b1d42 100644 --- a/Source/Thirdweb/Private/Wallets/ThirdwebInAppWalletHandle.cpp +++ b/Source/Thirdweb/Private/Wallets/ThirdwebInAppWalletHandle.cpp @@ -15,6 +15,25 @@ #include "Misc/DefaultValueHelper.h" +#define CHECK_ECOSYSTEM(ErrorDelegate) \ + if (UThirdwebRuntimeSettings::GetEcosystemId().IsEmpty()) \ + { \ + TW_LOG(Error, TEXT("Ecosystem ID not set in settings")) \ + if (ErrorDelegate.IsBound()) \ + { \ + ErrorDelegate.Execute(TEXT("Ecosystem ID not set in settings")); \ + } \ + return; \ + } + +#define CHECK_SOURCE(InSource) \ + if (Source != InSource) \ + { \ + TW_LOG(Error, TEXT("Wallet handle is not %s source"), FInAppWalletHandle::GetSourceString(InSource)) \ + ErrorDelegate.Execute(FString::Format(TEXT("Wallet handle is not %s source"), FInAppWalletHandle::GetSourceString(InSource))); \ + return; \ + } + FInAppWalletHandle::FInAppWalletHandle() { Type = InApp; @@ -60,185 +79,233 @@ bool FInAppWalletHandle::IsValid() const return Super::IsValid() && Source != InvalidSource; } -bool FInAppWalletHandle::CreateEmailWallet(const FString& Email, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateEmailWallet(const FString& Email, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (Thirdweb::create_in_app_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - TO_RUST_STRING(Email), - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - nullptr - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(EInAppSource::Email, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + + UE::Tasks::Launch(UE_SOURCE_LOCATION, [Email, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_in_app_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + TO_RUST_STRING(Email), + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + nullptr + ).AssignResult(Error)) + { + SuccessDelegate.Execute(FInAppWalletHandle(EInAppSource::Email, Error)); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateEcosystemEmailWallet(const FString& PartnerId, const FString& Email, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateEcosystemEmailWallet(const FString& PartnerId, const FString& Email, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (UThirdwebRuntimeSettings::GetEcosystemId().IsEmpty()) - { - Error = TEXT("Ecosystem ID not set in settings"); - return false; - } - if (Thirdweb::create_ecosystem_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), - TO_RUST_STRING(PartnerId), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - TO_RUST_STRING(Email), - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - nullptr - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(EInAppSource::Email, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [PartnerId, Email, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_ecosystem_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), + TO_RUST_STRING(PartnerId), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + TO_RUST_STRING(Email), + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + nullptr + ).AssignResult(Error)) + { + FInAppWalletHandle Wallet = FInAppWalletHandle(EInAppSource::Email, Error); + Wallet.EcosystemPartnerId = PartnerId; + SuccessDelegate.Execute(Wallet); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateOAuthWallet(const EThirdwebOAuthProvider Provider, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateOAuthWallet(const EThirdwebOAuthProvider Provider, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (Thirdweb::create_in_app_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - TO_RUST_STRING(ThirdwebUtils::ToString(Provider)) - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(Provider, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [Provider, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_in_app_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + TO_RUST_STRING(ThirdwebUtils::ToString(Provider)) + ).AssignResult(Error)) + { + SuccessDelegate.Execute(FInAppWalletHandle(Provider, Error)); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateEcosystemOAuthWallet(const FString& PartnerId, const EThirdwebOAuthProvider Provider, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateEcosystemOAuthWallet(const FString& PartnerId, + const EThirdwebOAuthProvider Provider, + const FCreateInAppWalletDelegate& SuccessDelegate, + const FStringDelegate& ErrorDelegate) { - if (UThirdwebRuntimeSettings::GetEcosystemId().IsEmpty()) - { - Error = TEXT("Ecosystem ID not set in settings"); - return false; - } - if (Thirdweb::create_ecosystem_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), - TO_RUST_STRING(PartnerId), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - TO_RUST_STRING(ThirdwebUtils::ToString(Provider)) - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(Provider, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [PartnerId, Provider, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_ecosystem_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), + TO_RUST_STRING(PartnerId), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + TO_RUST_STRING(ThirdwebUtils::ToString(Provider)) + ).AssignResult(Error)) + { + FInAppWalletHandle Wallet = FInAppWalletHandle(Provider, Error); + Wallet.EcosystemPartnerId = PartnerId; + SuccessDelegate.Execute(Wallet); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreatePhoneWallet(const FString& Phone, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreatePhoneWallet(const FString& Phone, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (Thirdweb::create_in_app_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - TO_RUST_STRING(Phone), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - nullptr - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(EInAppSource::Phone, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [Phone, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_in_app_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + TO_RUST_STRING(Phone), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + nullptr + ).AssignResult(Error)) + { + SuccessDelegate.Execute(FInAppWalletHandle(EInAppSource::Phone, Error)); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateEcosystemPhoneWallet(const FString& PartnerId, const FString& Phone, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateEcosystemPhoneWallet(const FString& PartnerId, const FString& Phone, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (Thirdweb::create_ecosystem_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), - TO_RUST_STRING(PartnerId), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - TO_RUST_STRING(Phone), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - nullptr - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(EInAppSource::Phone, Error); - Error.Empty(); - return true; - } - return false; + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [PartnerId, Phone, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_ecosystem_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), + TO_RUST_STRING(PartnerId), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + TO_RUST_STRING(Phone), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + nullptr + ).AssignResult(Error)) + { + FInAppWalletHandle Wallet = FInAppWalletHandle(EInAppSource::Phone, Error); + Wallet.EcosystemPartnerId = PartnerId; + SuccessDelegate.Execute(Wallet); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateCustomAuthWallet(const EInAppSource Source, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateCustomAuthWallet(const EInAppSource Source, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) if (Source != Jwt && Source != AuthEndpoint && Source != Guest) { - Error = TEXT("Invalid custom auth source"); - return false; - } - - if (Thirdweb::create_in_app_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - TO_RUST_STRING(FString(GetSourceString(Source))) - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(Source, Error); - Error.Empty(); - return true; - } - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid custom auth source")); + } + return; + } + UE::Tasks::Launch(UE_SOURCE_LOCATION, [Source, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_in_app_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + TO_RUST_STRING(FString(GetSourceString(Source))) + ).AssignResult(Error)) + { + SuccessDelegate.Execute(FInAppWalletHandle(Source, Error)); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FInAppWalletHandle::CreateEcosystemCustomAuthWallet(const FString& PartnerId, const EInAppSource Source, FInAppWalletHandle& Wallet, FString& Error) +void FInAppWalletHandle::CreateEcosystemCustomAuthWallet(const FString& PartnerId, const EInAppSource Source, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) if (Source != Jwt && Source != AuthEndpoint && Source != Guest) { - Error = TEXT("Invalid custom auth source"); - return false; - } - if (Thirdweb::create_ecosystem_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), - TO_RUST_STRING(PartnerId), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - nullptr, - nullptr, - TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), - TO_RUST_STRING(FString(GetSourceString(Source))) - ).AssignResult(Error)) - { - Wallet = FInAppWalletHandle(Source, Error); - Error.Empty(); - return true; - } - return false; + ErrorDelegate.Execute(TEXT("Invalid custom auth source")); + return; + } + UE::Tasks::Launch(UE_SOURCE_LOCATION, [PartnerId, Source, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_ecosystem_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetEcosystemId()), + TO_RUST_STRING(PartnerId), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + nullptr, + nullptr, + TO_RUST_STRING(UThirdwebRuntimeSettings::GetStorageDirectory()), + TO_RUST_STRING(FString(GetSourceString(Source))) + ).AssignResult(Error)) + { + FInAppWalletHandle Wallet = FInAppWalletHandle(Source, Error); + Wallet.EcosystemPartnerId = PartnerId; + SuccessDelegate.Execute(Wallet); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } bool FInAppWalletHandle::IsConnected() const @@ -251,96 +318,179 @@ void FInAppWalletHandle::Disconnect() const Thirdweb::disconnect(ID).Free(); } -bool FInAppWalletHandle::VerifyOTP(const EThirdwebOTPMethod Method, const FString& OTP, FString& Error) +void FInAppWalletHandle::SendOTP(const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) - { - Error = TEXT("Invalid wallet handle"); - return false; - } - if (Source != Email) - { - Error = TEXT("Wallet handle is not email source"); - return false; - } - if (UThirdwebRuntimeSettings::IsEcosystem()) + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] { - switch (Method) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - case EThirdwebOTPMethod::Phone: + switch (Source) { - if (Thirdweb::ecosystem_wallet_verify_otp_phone(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + case Phone: { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::ecosystem_wallet_send_otp_phone(ID).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + case Email: + { + if (Thirdweb::ecosystem_wallet_send_otp_email(ID).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + default: + { + ErrorDelegate.Execute(TEXT("Wallet handle is not email/phone source")); + return; } } - case EThirdwebOTPMethod::Email: + } + else + { + switch (Source) { - if (Thirdweb::ecosystem_wallet_verify_otp_email(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + case Phone: { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::in_app_wallet_send_otp_phone(ID).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + case Email: + { + if (Thirdweb::in_app_wallet_send_otp_email(ID).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + default: + { + ErrorDelegate.Execute(TEXT("Wallet handle is not email/phone source")); + return; } } } + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::SignInWithOTP(const FString& OTP, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Source != Phone && Source != Email) + { + ErrorDelegate.Execute(TEXT("Wallet handle is not email/phone OTP source")); + return; } - else + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, OTP, SuccessDelegate, ErrorDelegate] { - switch (Method) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - case EThirdwebOTPMethod::Phone: + switch (Source) { - if (Thirdweb::in_app_wallet_verify_otp_phone(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + case Phone: + { + if (Thirdweb::ecosystem_wallet_verify_otp_phone(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } + break; + } + case Email: { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::ecosystem_wallet_verify_otp_email(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } + break; } + default: return; } - case EThirdwebOTPMethod::Email: + } + else + { + switch (Source) { - if (Thirdweb::in_app_wallet_verify_otp_email(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + case Phone: + { + if (Thirdweb::in_app_wallet_verify_otp_phone(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } + } + case Email: { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::in_app_wallet_verify_otp_email(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } } + default: return; } } - } - - return false; + ErrorDelegate.Execute(Error); + }); } -bool FInAppWalletHandle::SendOTP(const EThirdwebOTPMethod Method, FString& Error) +void FInAppWalletHandle::LinkOTP(const FInAppWalletHandle& Wallet, const FString& OTP, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Wallet.GetSource() != Phone && Wallet.GetSource() != Email) { - Error = TEXT("Invalid wallet handle"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not email/phone OTP source")); + return; } - if (Source != Email) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Wallet, OTP, SuccessDelegate, ErrorDelegate] { - Error = TEXT("Wallet handle is not email source"); - return false; - } - if (UThirdwebRuntimeSettings::IsEcosystem()) - { - switch (Method) + FString Error; + switch (Source) { - case EThirdwebOTPMethod::Phone: return Thirdweb::ecosystem_wallet_send_otp_phone(ID).AssignResult(Error, true); - case EThirdwebOTPMethod::Email: return Thirdweb::ecosystem_wallet_send_otp_email(ID).AssignResult(Error, true); - } - } - else - { - switch (Method) - { - case EThirdwebOTPMethod::Phone: return Thirdweb::in_app_wallet_send_otp_phone(ID).AssignResult(Error, true); - case EThirdwebOTPMethod::Email: return Thirdweb::in_app_wallet_send_otp_email(ID).AssignResult(Error, true); + case Phone: + { + if (Thirdweb::ecosystem_wallet_link_account(ID, Wallet.GetID(), TO_RUST_STRING(OTP), nullptr, nullptr, nullptr).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + case Email: + { + if (Thirdweb::ecosystem_wallet_verify_otp_email(ID, TO_RUST_STRING(OTP)).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + break; + } + default: return; } - } - - return false; + ErrorDelegate.Execute(Error); + }); } bool FInAppWalletHandle::FetchOAuthLoginURL(const FString& RedirectUrl, FString& LoginLink, FString& Error) @@ -377,148 +527,263 @@ bool FInAppWalletHandle::FetchOAuthLoginURL(const FString& RedirectUrl, FString& return false; } -bool FInAppWalletHandle::SignInWithOAuth(const FString& AuthResult, FString& Error) +void FInAppWalletHandle::SignInWithOAuth(const FString& AuthResult, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) - { - Error = TEXT("Invalid wallet handle"); - return false; - } + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) if (Source != OAuthProvider) { - Error = TEXT("Wallet handle is not OAuth source"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not OAuth source")); + return; } FString Result = AuthResult; if (Result.StartsWith(TEXT("%7B%22"))) { Result = FGenericPlatformHttp::UrlDecode(AuthResult); } - if (UThirdwebRuntimeSettings::IsEcosystem()) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Result, SuccessDelegate, ErrorDelegate] { - if (Thirdweb::ecosystem_wallet_sign_in_with_oauth(ID, TO_RUST_STRING(Result)).AssignResult(Error, true)) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::ecosystem_wallet_sign_in_with_oauth(ID, TO_RUST_STRING(Result)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } } - } - else - { - if (Thirdweb::in_app_wallet_sign_in_with_oauth(ID, TO_RUST_STRING(Result)).AssignResult(Error, true)) + else { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::in_app_wallet_sign_in_with_oauth(ID, TO_RUST_STRING(Result)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } } - } - - return false; + ErrorDelegate.Execute(Error); + }); } -bool FInAppWalletHandle::SignInWithJwt(const FString& Jwt, FString& Error) +void FInAppWalletHandle::LinkOAuth(const FInAppWalletHandle& Wallet, const FString& AuthResult, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Wallet.GetSource() != OAuthProvider) { - Error = TEXT("Invalid wallet handle"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not OAuth source")); + return; } - if (Source != EInAppSource::Jwt) + FString Result = AuthResult; + if (Result.StartsWith(TEXT("%7B%22"))) { - Error = TEXT("Wallet handle is not JWT source"); - return false; + Result = FGenericPlatformHttp::UrlDecode(AuthResult); } - if (UThirdwebRuntimeSettings::IsEcosystem()) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Wallet, Result, SuccessDelegate, ErrorDelegate] { - if (Thirdweb::ecosystem_wallet_sign_in_with_jwt(ID, TO_RUST_STRING(Jwt)).AssignResult(Error, true)) + FString Error; + if (Thirdweb::ecosystem_wallet_link_account(ID, Wallet.GetID(), nullptr, TO_RUST_STRING(Result), nullptr, nullptr).AssignResult(Error, true)) { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + SuccessDelegate.Execute(); + return; } + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::SignInWithJwt(const FString& Jwt, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Source != EInAppSource::Jwt) + { + ErrorDelegate.Execute(TEXT("Wallet handle is not JWT source")); + return; } - else + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Jwt, SuccessDelegate, ErrorDelegate] { - if (UThirdwebRuntimeSettings::GetEncryptionKey().IsEmpty()) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - Error = TEXT("No encryption key set"); + if (Thirdweb::ecosystem_wallet_sign_in_with_jwt(ID, TO_RUST_STRING(Jwt)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } } else { + if (UThirdwebRuntimeSettings::GetEncryptionKey().IsEmpty()) + { + ErrorDelegate.Execute(TEXT("No encryption key set")); + return; + } if (Thirdweb::in_app_wallet_sign_in_with_jwt(ID, TO_RUST_STRING(Jwt), TO_RUST_STRING(UThirdwebRuntimeSettings::GetEncryptionKey())).AssignResult(Error, true)) { FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + SuccessDelegate.Execute(); + return; } } - } - - return false; + ErrorDelegate.Execute(Error); + }); } -bool FInAppWalletHandle::SignInWithAuthEndpoint(const FString& Payload, FString& Error) +void FInAppWalletHandle::LinkJwt(const FInAppWalletHandle& Wallet, const FString& Jwt, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) - { - Error = TEXT("Invalid wallet handle"); - return false; - } - if (Source != AuthEndpoint) + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Wallet.GetSource() != EInAppSource::Jwt) { - Error = TEXT("Wallet handle is not auth endpoint source"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not JWT source")); + return; } - if (UThirdwebRuntimeSettings::IsEcosystem()) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Wallet, Jwt, SuccessDelegate, ErrorDelegate] { - if (Thirdweb::ecosystem_wallet_sign_in_with_auth_endpoint(ID, TO_RUST_STRING(Payload)).AssignResult(Error, true)) + FString Error; + if (Thirdweb::ecosystem_wallet_link_account(ID, Wallet.GetID(), nullptr, nullptr, TO_RUST_STRING(Jwt), nullptr).AssignResult(Error, true)) { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + SuccessDelegate.Execute(); + return; } + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::SignInWithAuthEndpoint(const FString& Payload, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Source != AuthEndpoint) + { + ErrorDelegate.Execute(TEXT("Wallet handle is not auth endpoint source")); + return; } - else + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Payload, SuccessDelegate, ErrorDelegate] { - if (UThirdwebRuntimeSettings::GetEncryptionKey().IsEmpty()) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - Error = TEXT("No encryption key set"); - } else + if (Thirdweb::ecosystem_wallet_sign_in_with_auth_endpoint(ID, TO_RUST_STRING(Payload)).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } + } + else { + if (UThirdwebRuntimeSettings::GetEncryptionKey().IsEmpty()) + { + ErrorDelegate.Execute(TEXT("No encryption key set")); + return; + } if (Thirdweb::in_app_wallet_sign_in_with_auth_endpoint(ID, TO_RUST_STRING(Payload), TO_RUST_STRING(UThirdwebRuntimeSettings::GetEncryptionKey())).AssignResult(Error, true)) { FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + SuccessDelegate.Execute(); + return; } } - } - return false; + ErrorDelegate.Execute(Error); + }); } -bool FInAppWalletHandle::SignInWithGuest(FString& Error) +void FInAppWalletHandle::LinkAuthEndpoint(const FInAppWalletHandle& Wallet, const FString& Payload, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + if (Wallet.GetSource() != AuthEndpoint) { - Error = TEXT("Invalid wallet handle"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not auth endpoint source")); + return; } + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Wallet, Payload, SuccessDelegate, ErrorDelegate] + { + FString Error; + if (Thirdweb::ecosystem_wallet_link_account(ID, Wallet.GetID(), nullptr, nullptr, nullptr, TO_RUST_STRING(Payload)).AssignResult(Error, true)) + { + SuccessDelegate.Execute(); + return; + } + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::SignInWithGuest(const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) if (Source != Guest) { - Error = TEXT("Wallet handle is not guest source"); - return false; + ErrorDelegate.Execute(TEXT("Wallet handle is not guest source")); + return; } - if (UThirdwebRuntimeSettings::IsEcosystem()) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] { - if (Thirdweb::ecosystem_wallet_sign_in_with_guest(ID, TO_RUST_STRING(FPlatformMisc::GetLoginId())).AssignResult(Error, true)) + FString Error; + if (UThirdwebRuntimeSettings::IsEcosystem()) { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + if (Thirdweb::ecosystem_wallet_sign_in_with_guest(ID, TO_RUST_STRING(FPlatformMisc::GetLoginId())).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } + } + else + { + if (Thirdweb::in_app_wallet_sign_in_with_guest(ID, TO_RUST_STRING(FPlatformMisc::GetLoginId())).AssignResult(Error, true)) + { + FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); + SuccessDelegate.Execute(); + return; + } } + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::LinkGuest(const FInAppWalletHandle& Wallet, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) + if (Wallet.GetSource() != Guest) + { + ErrorDelegate.Execute(TEXT("Wallet handle is not guest source")); + return; } - else + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Wallet, SuccessDelegate, ErrorDelegate] { - if (Thirdweb::in_app_wallet_sign_in_with_guest(ID, TO_RUST_STRING(FPlatformMisc::GetLoginId())).AssignResult(Error, true)) + FString Error; + if (Thirdweb::ecosystem_wallet_link_account(ID, Wallet.GetID(), nullptr, nullptr, nullptr, TO_RUST_STRING(FPlatformMisc::GetLoginId())).AssignResult(Error, true)) { - FThirdwebAnalytics::SendConnectEvent(ToAddress(), GetTypeString()); - return true; + SuccessDelegate.Execute(); + return; } - } - return false; + ErrorDelegate.Execute(Error); + }); +} + +void FInAppWalletHandle::GetLinkedAccounts(const FGetLinkedAccountsDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + CHECK_ECOSYSTEM(ErrorDelegate) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] + { + FString Output; + if (Thirdweb::ecosystem_wallet_get_linked_accounts(ID).AssignResult(Output)) + { + TW_LOG(Warning, TEXT("FInAppWalletHandle::GetLinkedAccounts::%s"), *Output); + SuccessDelegate.Execute({Output}); + return; + } + ErrorDelegate.Execute(Output); + }); } FString FInAppWalletHandle::GetDisplayName() const diff --git a/Source/Thirdweb/Private/Wallets/ThirdwebSmartWalletHandle.cpp b/Source/Thirdweb/Private/Wallets/ThirdwebSmartWalletHandle.cpp index 98932d1..edbe337 100644 --- a/Source/Thirdweb/Private/Wallets/ThirdwebSmartWalletHandle.cpp +++ b/Source/Thirdweb/Private/Wallets/ThirdwebSmartWalletHandle.cpp @@ -30,66 +30,113 @@ FSmartWalletHandle::FSmartWalletHandle(const FInAppWalletHandle& InInAppWallet, ID = InID; } -FSmartWalletHandle FSmartWalletHandle::Create(const FInAppWalletHandle& InInAppWallet, const int64 ChainID, const bool bGasless, const FString& Factory, const FString& AccountOverride, bool& bSuccess, FString& Error) +void FSmartWalletHandle::Create(const FInAppWalletHandle& InInAppWallet, + const int64 ChainID, + const bool bGasless, + const FString& Factory, + const FString& AccountOverride, + const FCreateSmartWalletDelegate& SuccessDelegate, + const FStringDelegate& ErrorDelegate) { - bSuccess = false; - if (InInAppWallet.IsValid()) - { - if (bSuccess = Thirdweb::create_smart_wallet( - TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), - TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), - nullptr, - InInAppWallet.GetID(), - TO_RUST_STRING(FString::Printf(TEXT("%lld"), ChainID)), - bGasless, - TO_RUST_STRING(Factory), - TO_RUST_STRING(AccountOverride) - ).AssignResult(Error); bSuccess) + if (!SuccessDelegate.IsBound()) + { + if (ErrorDelegate.IsBound()) { - FSmartWalletHandle SmartWallet = FSmartWalletHandle(InInAppWallet, Error); - FThirdwebAnalytics::SendConnectEvent(SmartWallet.ToAddress(), SmartWallet.GetTypeString()); - Error.Empty(); - return SmartWallet; + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); } - } else + return; + } + if (!InInAppWallet.IsValid()) { - Error = TEXT("Invalid InApp wallet"); + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid InApp wallet")); + } + return; } - - return FSmartWalletHandle(); + UE::Tasks::Launch(UE_SOURCE_LOCATION, [InInAppWallet, ChainID, bGasless, Factory, AccountOverride, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::create_smart_wallet( + TO_RUST_STRING(UThirdwebRuntimeSettings::GetClientId()), + TO_RUST_STRING(UThirdwebRuntimeSettings::GetBundleId()), + nullptr, + InInAppWallet.GetID(), + TO_RUST_STRING(FString::Printf(TEXT("%lld"), ChainID)), + bGasless, + TO_RUST_STRING(Factory), + TO_RUST_STRING(AccountOverride) + ).AssignResult(Error)) + { + FSmartWalletHandle SmartWallet = FSmartWalletHandle(InInAppWallet, Error); + SuccessDelegate.Execute(SmartWallet); + FThirdwebAnalytics::SendConnectEvent(SmartWallet.ToAddress(), SmartWallet.GetTypeString()); + } + else + { + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(Error); + } + } + }); } -bool FSmartWalletHandle::IsDeployed(bool& bDeployed, FString& Error) +void FSmartWalletHandle::IsDeployed(const FBoolDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + if (!SuccessDelegate.IsBound()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; } - if (Thirdweb::smart_wallet_is_deployed(ID).AssignResult(Error)) + if (!IsValid()) { - bDeployed = Error.ToBool(); - Error.Empty(); - return true; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } - Error = TEXT("Not a networked wallet"); - return false; + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_is_deployed(ID).AssignResult(Error)) + { + SuccessDelegate.Execute(Error.ToBool()); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FSmartWalletHandle::CreateSessionKey(const FString& Signer, - const TArray& ApprovedTargets, - const FString& NativeTokenLimitPerTransactionInWei, - const FDateTime& PermissionStart, - const FDateTime& PermissionEnd, - const FDateTime& RequestValidityStart, - const FDateTime& RequestValidityEnd, - FString& TransactionHash, - FString& Error) +void FSmartWalletHandle::CreateSessionKey(const FString& Signer, + const TArray& ApprovedTargets, + const FString& NativeTokenLimitPerTransactionInWei, + const FDateTime& PermissionStart, + const FDateTime& PermissionEnd, + const FDateTime& RequestValidityStart, + const FDateTime& RequestValidityEnd, + const FStringDelegate& SuccessDelegate, + const FStringDelegate& ErrorDelegate) { + if (!SuccessDelegate.IsBound()) + { + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; + } if (!IsValid()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } FDateTime TenYearsFromNow = FDateTime::UtcNow() + FTimespan::FromDays(10 * 365); @@ -98,124 +145,217 @@ bool FSmartWalletHandle::CreateSessionKey(const FString& Signer, { ApprovedTargetsCArray.Add(TO_RUST_STRING(Target)); } - if (Thirdweb::smart_wallet_create_session_key( - ID, - TO_RUST_STRING(Signer), - ApprovedTargets.IsEmpty() ? nullptr : ApprovedTargetsCArray.GetData(), - ApprovedTargetsCArray.Num(), - TO_RUST_STRING(NativeTokenLimitPerTransactionInWei), - TO_RUST_TIMESTAMP(PermissionStart), - TO_RUST_TIMESTAMP(PermissionEnd), - TO_RUST_TIMESTAMP(RequestValidityStart), - TO_RUST_TIMESTAMP(RequestValidityEnd) - ).AssignResult(Error)) - { - TSharedPtr JsonObject = MakeShareable(new FJsonObject); - const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); - if (FJsonSerializer::Deserialize(Reader, JsonObject); JsonObject.IsValid()) - { - if (JsonObject->HasTypedField(TEXT("transactionHash"))) + UE::Tasks::Launch( + UE_SOURCE_LOCATION, + [this, Signer, ApprovedTargets, ApprovedTargetsCArray, NativeTokenLimitPerTransactionInWei, PermissionStart, PermissionEnd, RequestValidityStart, RequestValidityEnd, SuccessDelegate, + ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_create_session_key( + ID, + TO_RUST_STRING(Signer), + ApprovedTargets.IsEmpty() ? nullptr : ApprovedTargetsCArray.GetData(), + ApprovedTargetsCArray.Num(), + TO_RUST_STRING(NativeTokenLimitPerTransactionInWei), + TO_RUST_TIMESTAMP(PermissionStart), + TO_RUST_TIMESTAMP(PermissionEnd), + TO_RUST_TIMESTAMP(RequestValidityStart), + TO_RUST_TIMESTAMP(RequestValidityEnd) + ).AssignResult(Error)) { - TransactionHash = JsonObject->GetStringField(TEXT("transactionHash")); + TSharedPtr JsonObject = MakeShareable(new FJsonObject); + const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); + if (FJsonSerializer::Deserialize(Reader, JsonObject); JsonObject.IsValid()) + { + if (JsonObject->HasTypedField(TEXT("transactionHash"))) + { + SuccessDelegate.Execute(JsonObject->GetStringField(TEXT("transactionHash"))); + } + } } - } - Error.Empty(); - return true; - } - return false; + else + { + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(Error); + } + } + }); } -bool FSmartWalletHandle::GetAdmins(TArray& Admins, FString& Error) +void FSmartWalletHandle::RevokeSessionKey(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + if (!SuccessDelegate.IsBound()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; } - if (Thirdweb::smart_wallet_get_all_admins(ID).AssignResult(Error)) + if (!IsValid()) { - TArray> JsonValueArray; - const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); - FJsonSerializer::Deserialize(Reader, JsonValueArray); - for (int i = 0; i < JsonValueArray.Num(); i++) + if (ErrorDelegate.IsBound()) { - if (JsonValueArray[i]->Type == EJson::String) - { - Admins.Emplace(JsonValueArray[i]->AsString()); - } + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); } - Error.Empty(); - return true; + return; } - return false; + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Signer, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_revoke_session_key(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + { + SuccessDelegate.Execute(); + } + else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FSmartWalletHandle::GetActiveSigners(TArray& Signers, FString& Error) +void FSmartWalletHandle::GetAdmins(const FStringArrayDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { + if (!SuccessDelegate.IsBound()) + { + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; + } if (!IsValid()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } - if (Thirdweb::smart_wallet_get_all_active_signers(ID).AssignResult(Error)) + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] { - TArray> JsonValueArray; - const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); - FJsonSerializer::Deserialize(Reader, JsonValueArray); - for (int i = 0; i < JsonValueArray.Num(); i++) + TArray Admins; + if (FString Error; Thirdweb::smart_wallet_get_all_admins(ID).AssignResult(Error)) { - if (JsonValueArray[i]->Type == EJson::Object) + TArray> JsonValueArray; + const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); + FJsonSerializer::Deserialize(Reader, JsonValueArray); + for (int i = 0; i < JsonValueArray.Num(); i++) { - Signers.Emplace(FSigner::FromJson(JsonValueArray[i]->AsObject())); + if (JsonValueArray[i]->Type == EJson::String) + { + Admins.Emplace(JsonValueArray[i]->AsString()); + } } + SuccessDelegate.Execute(Admins); } - Error.Empty(); - return true; - } - return false; + else + { + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(Error); + } + } + }); } -bool FSmartWalletHandle::RevokeSessionKey(const FString& Signer, FString& Error) +void FSmartWalletHandle::AddAdmin(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + if (!SuccessDelegate.IsBound()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; } - if (Thirdweb::smart_wallet_revoke_session_key(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + if (!IsValid()) { - Error.Empty(); - return true; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } - return false;; + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Signer, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_add_admin(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + { + SuccessDelegate.Execute(); + } else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FSmartWalletHandle::AddAdmin(const FString& Signer, FString& Error) +void FSmartWalletHandle::RemoveAdmin(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + if (!SuccessDelegate.IsBound()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; } - if (Thirdweb::smart_wallet_add_admin(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + if (!IsValid()) { - Error.Empty(); - return true; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } - return false; + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Signer, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_remove_admin(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + { + SuccessDelegate.Execute(); + } else + { + ErrorDelegate.Execute(Error); + } + }); } -bool FSmartWalletHandle::RemoveAdmin(const FString& Signer, FString& Error) +void FSmartWalletHandle::GetActiveSigners(const FGetActiveSignersDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { - if (!IsValid()) + if (!SuccessDelegate.IsBound()) { - Error = TEXT("Invalid smart wallet"); - return false; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); + } + return; } - if (Thirdweb::smart_wallet_remove_admin(ID, TO_RUST_STRING(Signer)).AssignResult(Error)) + if (!IsValid()) { - Error.Empty(); - return true; + if (ErrorDelegate.IsBound()) + { + ErrorDelegate.Execute(TEXT("Invalid smart wallet handle")); + } + return; } - return false; -} \ No newline at end of file + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::smart_wallet_get_all_active_signers(ID).AssignResult(Error)) + { + TArray Signers; + TArray> JsonValueArray; + const TSharedRef> Reader = TJsonReaderFactory<>::Create(Error); + FJsonSerializer::Deserialize(Reader, JsonValueArray); + for (int i = 0; i < JsonValueArray.Num(); i++) + { + if (JsonValueArray[i]->Type == EJson::Object) + { + Signers.Emplace(FSigner::FromJson(JsonValueArray[i]->AsObject())); + } + } + SuccessDelegate.Execute(Signers); + } + else + { + ErrorDelegate.Execute(Error); + } + }); +} diff --git a/Source/Thirdweb/Private/Wallets/ThirdwebWalletHandle.cpp b/Source/Thirdweb/Private/Wallets/ThirdwebWalletHandle.cpp index 8855b24..11cda22 100644 --- a/Source/Thirdweb/Private/Wallets/ThirdwebWalletHandle.cpp +++ b/Source/Thirdweb/Private/Wallets/ThirdwebWalletHandle.cpp @@ -21,11 +21,25 @@ #include "Serialization/JsonReader.h" #include "Serialization/JsonSerializer.h" - FString FWalletHandle::ToAddress() const { FString Result; return Thirdweb::get_wallet_address(ID).AssignResult(Result) ? Result : ThirdwebUtils::ZeroAddress; } -FString FWalletHandle::Sign(const FString& Message) const { return Thirdweb::sign_message(ID, TO_RUST_STRING(Message)).GetOutput(); } +void FWalletHandle::Sign(const FString& Message, const FStringDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) const +{ + CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) + CHECK_VALIDITY(ErrorDelegate) + + UE::Tasks::Launch(UE_SOURCE_LOCATION, [this, Message, SuccessDelegate, ErrorDelegate] + { + if (FString Error; Thirdweb::sign_message(ID, TO_RUST_STRING(Message)).AssignResult(Error)) + { + SuccessDelegate.Execute(Error); + } else + { + ErrorDelegate.Execute(Error); + } + }); +} diff --git a/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebBase.h b/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebBase.h new file mode 100644 index 0000000..4204308 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebBase.h @@ -0,0 +1,19 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "Kismet/BlueprintAsyncActionBase.h" + +#include "AsyncTaskThirdwebBase.generated.h" + +#define NEW_TASK ThisClass* Task = NewObject(WorldContextObject); + +UCLASS(Abstract) +class UAsyncTaskThirdwebBase : public UBlueprintAsyncActionBase +{ + GENERATED_BODY() + +public: + DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FErrorOnlyDelegate, const FString&, Error); + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.h b/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.h index 44e4387..f2938c0 100644 --- a/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.h +++ b/Source/Thirdweb/Public/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.h @@ -3,8 +3,7 @@ #pragma once #include "Wallets/ThirdwebInAppWalletHandle.h" - -#include "Kismet/BlueprintAsyncActionBase.h" +#include "Wallets/InApp/AsyncTaskThirdwebInAppBase.h" #include "AsyncTaskThirdwebLoginWithOAuth.generated.h" @@ -13,36 +12,37 @@ class UThirdwebOAuthBrowserUserWidget; /** * */ -UCLASS(Blueprintable, BlueprintType, ClassGroup="Thirdweb|Authentication") -class THIRDWEB_API UAsyncTaskThirdwebLoginWithOAuth : public UBlueprintAsyncActionBase +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLoginWithOAuth : public UAsyncTaskThirdwebInAppBase { GENERATED_BODY() public: - virtual void Activate() override; UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|In App") static UAsyncTaskThirdwebLoginWithOAuth* LoginWithOAuth(UObject* WorldContextObject, const FInAppWalletHandle& Wallet); - DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOAuthDelegate, const FString&, Message); UPROPERTY(BlueprintAssignable) - FOAuthDelegate Success; + FErrorOnlyDelegate Success; UPROPERTY(BlueprintAssignable) - FOAuthDelegate Failed; + FErrorOnlyDelegate Failed; protected: UPROPERTY(Transient) UThirdwebOAuthBrowserUserWidget* Browser; - + UPROPERTY(Transient) FInAppWalletHandle Wallet; - + private: UFUNCTION() - void HandleFailed(const FString& Error); + void HandleAuthenticated(const FString& AuthResult); UFUNCTION() - void HandleAuthenticated(const FString& AuthResult); + virtual void HandleSignedIn(); + + UFUNCTION() + void HandleFailed(const FString& Error); }; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.h new file mode 100644 index 0000000..c7b8447 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebGetLinkedAccounts.h @@ -0,0 +1,32 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppBase.h" +#include "AsyncTaskThirdwebGetLinkedAccounts.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebGetLinkedAccounts : public UAsyncTaskThirdwebInAppBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebGetLinkedAccounts* GetLinkedAccounts(UObject* WorldContextObject, const FInAppWalletHandle& Wallet); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FGetLinkedAccountsDelegate, const TArray&, LinkedAccounts, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FGetLinkedAccountsDelegate Success; + + UPROPERTY(BlueprintAssignable) + FGetLinkedAccountsDelegate Failed; + +private: + UFUNCTION() + void HandleResponse(const TArray& LinkedAccounts); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppBase.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppBase.h new file mode 100644 index 0000000..e060564 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppBase.h @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/AsyncTaskThirdwebBase.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +#include "AsyncTaskThirdwebInAppBase.generated.h" + + +/** + * + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebInAppBase : public UAsyncTaskThirdwebBase +{ + GENERATED_BODY() + +protected: + UPROPERTY(Transient) + FInAppWalletHandle InAppWallet; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.h new file mode 100644 index 0000000..d19dfcf --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.h @@ -0,0 +1,36 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppBase.h" +#include "AsyncTaskThirdwebInAppSignMessage.generated.h" + +UCLASS() +class THIRDWEB_API UAsyncTaskThirdwebInAppSignMessage : public UAsyncTaskThirdwebInAppBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AutoCreateRefTerm="Message"), DisplayName="Sign Message", Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebInAppSignMessage* SignMessage(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FString& Message); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSignMessageDelegate, const FString&, SignedMessage, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FSignMessageDelegate Success; + + UPROPERTY(BlueprintAssignable) + FSignMessageDelegate Failed; + +protected: + UPROPERTY(Transient) + FString UnsignedMessage; + +private: + UFUNCTION() + void HandleResponse(const FString& SignedMessage); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.h new file mode 100644 index 0000000..084d87e --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/AsyncTaskThirdwebSendOTP.h @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppBase.h" +#include "AsyncTaskThirdwebSendOTP.generated.h" + +/** + * Sends an OTP for the in-app wallet + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSendOTP : public UAsyncTaskThirdwebInAppBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Send OTP", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSendOTP* SendOTP(UObject* WorldContextObject, const FInAppWalletHandle& Wallet); + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +private: + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.h new file mode 100644 index 0000000..a410eb3 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.h @@ -0,0 +1,18 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreateAuthEndpointWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateAuthEndpointWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreateAuthEndpointWallet* CreateAuthEndpointWallet(UObject* WorldContextObject, const FString& PartnerId) { CREATE_WALLET_TASK } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.h new file mode 100644 index 0000000..1e34cbe --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreateEmailWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateEmailWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreateEmailWallet* CreateEmailWallet(UObject* WorldContextObject, UPARAM(DisplayName="Email Address") const FString& Input, const FString& PartnerId) + { + CREATE_WALLET_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.h new file mode 100644 index 0000000..eedc095 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.h @@ -0,0 +1,18 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreateGuestWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateGuestWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreateGuestWallet* CreateGuestWallet(UObject* WorldContextObject, const FString& PartnerId) { CREATE_WALLET_TASK } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.h new file mode 100644 index 0000000..63b1f28 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.h @@ -0,0 +1,18 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreateJwtWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateJwtWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, DisplayName="Create JWT Wallet", meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreateJwtWallet* CreateJwtWallet(UObject* WorldContextObject, const FString& PartnerId) { CREATE_WALLET_TASK } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.h new file mode 100644 index 0000000..82a0e8d --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.h @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreateOAuthWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateOAuthWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreateOAuthWallet* CreateOAuthWallet(UObject* WorldContextObject, const EThirdwebOAuthProvider Provider, const FString& PartnerId); + +protected: + UPROPERTY(Transient) + EThirdwebOAuthProvider Provider; + +public: + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.h new file mode 100644 index 0000000..1726a88 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebInAppCreateWalletBase.h" +#include "AsyncTaskThirdwebCreatePhoneWallet.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreatePhoneWallet : public UAsyncTaskThirdwebInAppCreateWalletBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebCreatePhoneWallet* CreatePhoneWallet(UObject* WorldContextObject, UPARAM(DisplayName="Phone Number") const FString& Input, const FString& PartnerId) + { + CREATE_WALLET_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.h new file mode 100644 index 0000000..d6e59e9 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.h @@ -0,0 +1,59 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/AsyncTaskThirdwebBase.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" + +#include "AsyncTaskThirdwebCreateSmartWallet.generated.h" + +struct FSmartWalletHandle; + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateSmartWallet : public UAsyncTaskThirdwebBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="Factory,AccountOverride"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebCreateSmartWallet* CreateSmartWallet(UObject* WorldContextObject, + const FInAppWalletHandle& InAppWallet, + const int64 ChainID, + const bool bGasless = true, + const FString& Factory = "", + const FString& AccountOverride = ""); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCreateSmartWalletDelegate, const FSmartWalletHandle&, SmartWallet, const FString&, Error); + + UPROPERTY(BlueprintAssignable) + FCreateSmartWalletDelegate Success; + + UPROPERTY(BlueprintAssignable) + FCreateSmartWalletDelegate Failed; + +protected: + UPROPERTY(Transient) + FInAppWalletHandle InAppWallet; + + UPROPERTY(Transient) + int64 ChainID; + + UPROPERTY(Transient) + bool bGasless; + + UPROPERTY(Transient) + FString Factory; + + UPROPERTY(Transient) + FString AccountOverride; + +private: + UFUNCTION() + void HandleResponse(const FSmartWalletHandle& Wallet); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.h new file mode 100644 index 0000000..507800e --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebInAppCreateWalletBase.h @@ -0,0 +1,63 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/AsyncTaskThirdwebBase.h" + +#include "Components/SlateWrapperTypes.h" + +#include "AsyncTaskThirdwebInAppCreateWalletBase.generated.h" + +#define BIND_CREATE_WALLET_SUCCESS_DELEGATE BIND_UOBJECT_DELEGATE(FInAppWalletHandle::FCreateInAppWalletDelegate, HandleResponse) +#define BIND_CREATE_WALLET_ERROR_DELEGATE BIND_UOBJECT_DELEGATE(FStringDelegate, HandleFailed) + +#define CREATE_WALLET_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->EcosystemPartnerId = PartnerId; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +#define CREATE_WALLET_INPUT_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->AuthInput = Input; \ + Task->EcosystemPartnerId = PartnerId; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +struct FInAppWalletHandle; + +UCLASS(Abstract) +class UAsyncTaskThirdwebInAppCreateWalletBase : public UAsyncTaskThirdwebBase +{ + GENERATED_BODY() + +public: + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCreateInAppWalletDelegate, const FInAppWalletHandle&, Wallet, const FString&, Error); + + UPROPERTY(BlueprintAssignable) + FCreateInAppWalletDelegate Success; + + UPROPERTY(BlueprintAssignable) + FCreateInAppWalletDelegate Failed; + +protected: + UPROPERTY(Transient) + FString AuthInput; + + UPROPERTY(Transient) + FString EcosystemPartnerId; + + UFUNCTION() + void HandleResponse(const FInAppWalletHandle& Wallet); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.h new file mode 100644 index 0000000..15066c5 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.h @@ -0,0 +1,22 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLink.generated.h" + +UCLASS() +class THIRDWEB_API UAsyncTaskThirdwebLink : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + /** Multi-Purpose runtime link node covering all link options based upon Wallet. Input is ignored if guest wallet */ + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLink* Link(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FInAppWalletHandle& NewWallet, const FString& Input) + { + LINK_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.h new file mode 100644 index 0000000..eb8dff7 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkAuthEndpoint.h @@ -0,0 +1,24 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLinkAuthEndpoint.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLinkAuthEndpoint : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link Auth Endpoint", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLinkAuthEndpoint* LinkAuthEndpoint(UObject* WorldContextObject, + const FInAppWalletHandle& Wallet, + const FInAppWalletHandle& NewWallet, + UPARAM(DisplayName="Payload") const FString& Input) + { + LINK_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.h new file mode 100644 index 0000000..15f8a28 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkBase.h @@ -0,0 +1,56 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppBase.h" + +#include "AsyncTaskThirdwebLinkBase.generated.h" + +#define LINK_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->InAppWallet = Wallet; \ + Task->NewInAppWallet = NewWallet; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +#define LINK_INPUT_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->InAppWallet = Wallet; \ + Task->NewInAppWallet = NewWallet; \ + Task->AuthInput = Input; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +UCLASS(Abstract) +class THIRDWEB_API UAsyncTaskThirdwebLinkBase : public UAsyncTaskThirdwebInAppBase +{ + GENERATED_BODY() + +public: + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +protected: + UPROPERTY(Transient) + FInAppWalletHandle NewInAppWallet; + + UPROPERTY(Transient) + FString AuthInput; + + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.h new file mode 100644 index 0000000..8c3d46b --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkGuest.h @@ -0,0 +1,18 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLinkGuest.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLinkGuest : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link Guest", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLinkGuest* LinkGuest(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FInAppWalletHandle& NewWallet) { LINK_TASK } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.h new file mode 100644 index 0000000..fd9ca55 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkJwt.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLinkJwt.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLinkJwt : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link JWT", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLinkJwt* LinkJwt(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FInAppWalletHandle& NewWallet, UPARAM(DisplayName="JWT") const FString& Input) + { + LINK_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.h new file mode 100644 index 0000000..df5cd84 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOAuth.h @@ -0,0 +1,24 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLinkOAuth.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLinkOAuth : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link OAuth", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLinkOAuth* LinkOAuth(UObject* WorldContextObject, + const FInAppWalletHandle& Wallet, + const FInAppWalletHandle& NewWallet, + UPARAM(DisplayName="Auth Result") const FString& Input) + { + LINK_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.h new file mode 100644 index 0000000..1be4420 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLinkOTP.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebLinkBase.h" +#include "AsyncTaskThirdwebLinkOTP.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebLinkOTP : public UAsyncTaskThirdwebLinkBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Link OTP", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebLinkOTP* LinkOTP(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FInAppWalletHandle& NewWallet, UPARAM(DisplayName="OTP") const FString& Input) + { + LINK_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.h new file mode 100644 index 0000000..16e920c --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.h @@ -0,0 +1,22 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignIn.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignIn : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + /** Multi-Purpose runtime sign-in node covering all sign in options based upon Wallet. Input is ignored if guest wallet */ + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSignIn* SignIn(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, const FString& Input) + { + SIGN_IN_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInBase.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInBase.h new file mode 100644 index 0000000..9aec75b --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInBase.h @@ -0,0 +1,51 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppBase.h" + +#include "AsyncTaskThirdwebSignInBase.generated.h" + +#define SIGN_IN_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->InAppWallet = Wallet; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +#define SIGN_IN_INPUT_TASK \ + if (!WorldContextObject) \ + { \ + return nullptr; \ + } \ + ThisClass* Task = NewObject(WorldContextObject); \ + Task->InAppWallet = Wallet; \ + Task->AuthInput = Input; \ + Task->RegisterWithGameInstance(WorldContextObject); \ + return Task; + +UCLASS(Abstract) +class THIRDWEB_API UAsyncTaskThirdwebSignInBase : public UAsyncTaskThirdwebInAppBase +{ + GENERATED_BODY() + +public: + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +protected: + UPROPERTY(Transient) + FString AuthInput; + + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.h new file mode 100644 index 0000000..3b73445 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithAuthEndpoint.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignInWithAuthEndpoint.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignInWithAuthEndpoint : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In With Auth Endpoint", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSignInWithAuthEndpoint* SignInWithAuthEndpoint(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, UPARAM(DisplayName="Payload") const FString& Input) + { + SIGN_IN_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.h new file mode 100644 index 0000000..a6a8741 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithGuest.h @@ -0,0 +1,18 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignInWithGuest.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignInWithGuest : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In With Guest", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSignInWithGuest* SignInWithGuest(UObject* WorldContextObject, const FInAppWalletHandle& Wallet) { SIGN_IN_TASK } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.h new file mode 100644 index 0000000..f4c15ef --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithJwt.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignInWithJwt.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignInWithJwt : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In With JWT", Category="Thirdweb|Wallets|InApp") + static UAsyncTaskThirdwebSignInWithJwt* SignInWithJwt(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, UPARAM(DisplayName="JWT") const FString& Input) + { + SIGN_IN_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.h new file mode 100644 index 0000000..14f92f5 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOAuth.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignInWithOAuth.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignInWithOAuth : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In With OAuth", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSignInWithOAuth* SignInWithOAuth(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, UPARAM(DisplayName="Auth Result") const FString& Input) + { + SIGN_IN_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.h new file mode 100644 index 0000000..7aab1e7 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignInWithOTP.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSignInBase.h" +#include "AsyncTaskThirdwebSignInWithOTP.generated.h" + +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSignInWithOTP : public UAsyncTaskThirdwebSignInBase +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), DisplayName="Sign In With OTP", Category="Thirdweb|Wallets|In App") + static UAsyncTaskThirdwebSignInWithOTP* SignInWithOTP(UObject* WorldContextObject, const FInAppWalletHandle& Wallet, UPARAM(DisplayName="OTP") const FString& Input) + { + SIGN_IN_INPUT_TASK + } + + virtual void Activate() override; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.h new file mode 100644 index 0000000..8a85e50 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebAddAdmin.h @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebAddAdmin.generated.h" + +/** + * Revoke the session key of a smart wallet signer + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebAddAdmin : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebAddAdmin* AddAdmin(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer); + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +protected: + UPROPERTY(Transient) + FString Signer; + +private: + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.h new file mode 100644 index 0000000..acbd761 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebCreateSessionKey.h @@ -0,0 +1,66 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebCreateSessionKey.generated.h" + +/** + * Create a session key for a smart wallet + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebCreateSessionKey : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AdvancedDisplay="PermissionStart,PermissionEnd,RequestValidityStart,RequestValidityEnd", + AutoCreateRefTerm="PermissionStart,PermissionEnd,RequestValidityStart,RequestValidityEnd,ApprovedTargets,Signer,NativeTokenLimitPerTransactionInWei"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebCreateSessionKey* CreateSessionKey(UObject* WorldContextObject, + const FSmartWalletHandle& Wallet, + const FString& Signer, + const TArray& ApprovedTargets, + const FString& NativeTokenLimitPerTransactionInWei, + const FDateTime& PermissionStart, + const FDateTime& PermissionEnd, + const FDateTime& RequestValidityStart, + const FDateTime& RequestValidityEnd); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCreateSessionKeyDelegate, const FString&, TxHash, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FCreateSessionKeyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FCreateSessionKeyDelegate Failed; + +protected: + UPROPERTY(Transient) + FString Signer; + + UPROPERTY(Transient) + TArray ApprovedTargets; + + UPROPERTY(Transient) + FString NativeTokenLimitPerTransactionInWei; + + UPROPERTY(Transient) + FDateTime PermissionStart; + + UPROPERTY(Transient) + FDateTime PermissionEnd; + + UPROPERTY(Transient) + FDateTime RequestValidityStart; + + UPROPERTY(Transient) + FDateTime RequestValidityEnd; + +private: + UFUNCTION() + void HandleResponse(const FString& TxHash); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetActiveSigners.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetActiveSigners.h new file mode 100644 index 0000000..98f1a2e --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetActiveSigners.h @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebGetActiveSigners.generated.h" + +/** + * Get all active signers of a smart wallet + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebGetActiveSigners : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebGetActiveSigners* GetActiveSigners(UObject* WorldContextObject, const FSmartWalletHandle& Wallet); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FGetActiveSignersDelegate, const TArray&, ActiveSigners, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FGetActiveSignersDelegate Success; + + UPROPERTY(BlueprintAssignable) + FGetActiveSignersDelegate Failed; + +private: + UFUNCTION() + void HandleIsDeployedResponse(const bool& bDeployed); + + UFUNCTION() + void HandleResponse(const TArray& Signers); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.h new file mode 100644 index 0000000..8970eea --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebGetAdmins.h @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebGetAdmins.generated.h" + +/** + * Get all admins of a smart wallet + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebGetAdmins : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebGetAdmins* GetAdmins(UObject* WorldContextObject, const FSmartWalletHandle& Wallet); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FGetAdminsDelegate, const TArray&, Admins, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FGetAdminsDelegate Success; + + UPROPERTY(BlueprintAssignable) + FGetAdminsDelegate Failed; +private: + UFUNCTION() + void HandleResponse(const TArray& Admins); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.h new file mode 100644 index 0000000..c71cb03 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsActiveSigner.h @@ -0,0 +1,42 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebIsActiveSigner.generated.h" + +/** + * Checks whether the provided backend wallet is currently an active signer or not + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebIsActiveSigner : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebIsActiveSigner* IsActiveSigner(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& BackendWallet); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FIsActiveSignerDelegate, const bool, bActiveSigner, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FIsActiveSignerDelegate Success; + + UPROPERTY(BlueprintAssignable) + FIsActiveSignerDelegate Failed; + +protected: + UPROPERTY(Transient) + FString BackendWallet; + +private: + UFUNCTION() + void HandleIsDeployedResponse(const bool& bDeployed); + + UFUNCTION() + void HandleResponse(const TArray& Signers); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.h new file mode 100644 index 0000000..912b02a --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebIsDeployed.h @@ -0,0 +1,37 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebIsDeployed.generated.h" + +/** + * Check if a smart wallet is deployed + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebIsDeployed : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebIsDeployed* IsDeployed(UObject* WorldContextObject, const FSmartWalletHandle& Wallet); + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Deployed; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate NotDeployed; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +private: + UFUNCTION() + void HandleResponse(const bool& bIsDeployed); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.h new file mode 100644 index 0000000..a2199fb --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRemoveAdmin.h @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebRemoveAdmin.generated.h" + +/** + * Revoke the session key of a smart wallet signer + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebRemoveAdmin : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebRemoveAdmin* RemoveAdmin(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer); + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; + +protected: + UPROPERTY(Transient) + FString Signer; + +private: + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.h new file mode 100644 index 0000000..0c803fc --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebRevokeSessionKey.h @@ -0,0 +1,37 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebRevokeSessionKey.generated.h" + +/** + * Revoke the session key of a smart wallet signer + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebRevokeSessionKey : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject"), Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebRevokeSessionKey* RevokeSessionKey(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Signer); + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Success; + + UPROPERTY(BlueprintAssignable) + FErrorOnlyDelegate Failed; +protected: + UPROPERTY(Transient) + FString Signer; + +private: + UFUNCTION() + void HandleResponse(); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartBase.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartBase.h new file mode 100644 index 0000000..7e8e107 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartBase.h @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTasks/AsyncTaskThirdwebBase.h" + +#include "Wallets/ThirdwebSmartWalletHandle.h" + +#include "AsyncTaskThirdwebSmartBase.generated.h" + + +/** + * + */ +UCLASS(Blueprintable, BlueprintType) +class THIRDWEB_API UAsyncTaskThirdwebSmartBase : public UAsyncTaskThirdwebBase +{ + GENERATED_BODY() + +protected: + UPROPERTY(Transient) + FSmartWalletHandle SmartWallet; +}; diff --git a/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.h b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.h new file mode 100644 index 0000000..d75d443 --- /dev/null +++ b/Source/Thirdweb/Public/AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.h @@ -0,0 +1,37 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "AsyncTaskThirdwebSmartBase.h" +#include "AsyncTaskThirdwebSmartSignMessage.generated.h" + + +UCLASS() +class THIRDWEB_API UAsyncTaskThirdwebSmartSignMessage : public UAsyncTaskThirdwebSmartBase +{ + GENERATED_BODY() + +public: + virtual void Activate() override; + + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly="true", WorldContext="WorldContextObject", AutoCreateRefTerm="Message"), DisplayName="Sign Message", Category="Thirdweb|Wallets|Smart") + static UAsyncTaskThirdwebSmartSignMessage* SignMessage(UObject* WorldContextObject, const FSmartWalletHandle& Wallet, const FString& Message); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSignMessageDelegate, const FString&, SignedMessage, const FString&, Error); + UPROPERTY(BlueprintAssignable) + FSignMessageDelegate Success; + + UPROPERTY(BlueprintAssignable) + FSignMessageDelegate Failed; + +protected: + UPROPERTY(Transient) + FString UnsignedMessage; + +private: + UFUNCTION() + void HandleResponse(const FString& SignedMessage); + + UFUNCTION() + virtual void HandleFailed(const FString& Error); +}; diff --git a/Source/Thirdweb/Public/Browser/ThirdwebOAuthExternalBrowser.h b/Source/Thirdweb/Public/Browser/ThirdwebOAuthExternalBrowser.h index abb0905..b84b749 100644 --- a/Source/Thirdweb/Public/Browser/ThirdwebOAuthExternalBrowser.h +++ b/Source/Thirdweb/Public/Browser/ThirdwebOAuthExternalBrowser.h @@ -52,5 +52,4 @@ class UThirdwebOAuthExternalBrowser : public UObject, public FTickableGameObject FHttpRouteHandle RouteHandle; TSharedPtr Router; EState State; - }; diff --git a/Source/Thirdweb/Public/Data/ThirdwebCountryCodes.h b/Source/Thirdweb/Public/Data/ThirdwebCountryCodes.h new file mode 100644 index 0000000..0e7c33d --- /dev/null +++ b/Source/Thirdweb/Public/Data/ThirdwebCountryCodes.h @@ -0,0 +1,278 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +// Warning: The information provided in this file is for convenience, and is subject to change at any time. + +#pragma once + +#include "ThirdwebCountryCodes.generated.h" + +USTRUCT(BlueprintType, DisplayName="Country Code") +struct THIRDWEB_API FThirdwebCountryCode +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadOnly) + int32 Code = 0; + + UPROPERTY(EditAnywhere, BlueprintReadOnly) + FText Abbreviation; + + UPROPERTY(EditAnywhere, BlueprintReadOnly) + FText FullName; +}; + +#define LOCTEXT_NAMESPACE "Thirdweb" +#define LOCTEXT_LOCAL(Value) LOCTEXT(Value, Value) + +namespace ThirdwebCountryCodes +{ + static TMap Map = { + {376, {376, LOCTEXT_LOCAL("AD"), LOCTEXT_LOCAL("Andorra")}}, + {971, {971, LOCTEXT_LOCAL("AE"), LOCTEXT_LOCAL("United Arab Emirates")}}, + {93, {93, LOCTEXT_LOCAL("AF"), LOCTEXT_LOCAL("Afghanistan")}}, + {1268, {1268, LOCTEXT_LOCAL("AG"), LOCTEXT_LOCAL("Antigua and Barbuda")}}, + {1264, {1264, LOCTEXT_LOCAL("AI"), LOCTEXT_LOCAL("Anguilla")}}, + {355, {355, LOCTEXT_LOCAL("AL"), LOCTEXT_LOCAL("Albania")}}, + {374, {374, LOCTEXT_LOCAL("AM"), LOCTEXT_LOCAL("Armenia")}}, + {599, {599, LOCTEXT_LOCAL("AN"), LOCTEXT_LOCAL("Netherlands Antilles")}}, + {244, {244, LOCTEXT_LOCAL("AO"), LOCTEXT_LOCAL("Angola")}}, + {672, {672, LOCTEXT_LOCAL("AQ"), LOCTEXT_LOCAL("Antarctica")}}, + {54, {54, LOCTEXT_LOCAL("AR"), LOCTEXT_LOCAL("Argentina")}}, + {1684, {1684, LOCTEXT_LOCAL("AS"), LOCTEXT_LOCAL("American Samoa")}}, + {43, {43, LOCTEXT_LOCAL("AT"), LOCTEXT_LOCAL("Austria")}}, + {61, {61, LOCTEXT_LOCAL("AU"), LOCTEXT_LOCAL("Australia")}}, + {297, {297, LOCTEXT_LOCAL("AW"), LOCTEXT_LOCAL("Aruba")}}, + {35818, {35818, LOCTEXT_LOCAL("AX"), LOCTEXT_LOCAL("Aland Islands")}}, + {994, {994, LOCTEXT_LOCAL("AZ"), LOCTEXT_LOCAL("Azerbaijan")}}, + {387, {387, LOCTEXT_LOCAL("BA"), LOCTEXT_LOCAL("Bosnia and Herzegovina")}}, + {1246, {1246, LOCTEXT_LOCAL("BB"), LOCTEXT_LOCAL("Barbados")}}, + {880, {880, LOCTEXT_LOCAL("BD"), LOCTEXT_LOCAL("Bangladesh")}}, + {32, {32, LOCTEXT_LOCAL("BE"), LOCTEXT_LOCAL("Belgium")}}, + {226, {226, LOCTEXT_LOCAL("BF"), LOCTEXT_LOCAL("Burkina Faso")}}, + {359, {359, LOCTEXT_LOCAL("BG"), LOCTEXT_LOCAL("Bulgaria")}}, + {973, {973, LOCTEXT_LOCAL("BH"), LOCTEXT_LOCAL("Bahrain")}}, + {257, {257, LOCTEXT_LOCAL("BI"), LOCTEXT_LOCAL("Burundi")}}, + {229, {229, LOCTEXT_LOCAL("BJ"), LOCTEXT_LOCAL("Benin")}}, + {590, {590, LOCTEXT_LOCAL("BL"), LOCTEXT_LOCAL("Saint Barthelemy")}}, + {1441, {1441, LOCTEXT_LOCAL("BM"), LOCTEXT_LOCAL("Bermuda")}}, + {673, {673, LOCTEXT_LOCAL("BN"), LOCTEXT_LOCAL("Brunei Darussalam")}}, + {591, {591, LOCTEXT_LOCAL("BO"), LOCTEXT_LOCAL("Bolivia")}}, + {55, {55, LOCTEXT_LOCAL("BR"), LOCTEXT_LOCAL("Brazil")}}, + {1242, {1242, LOCTEXT_LOCAL("BS"), LOCTEXT_LOCAL("Bahamas")}}, + {975, {975, LOCTEXT_LOCAL("BT"), LOCTEXT_LOCAL("Bhutan")}}, + {47, {47, LOCTEXT_LOCAL("BV"), LOCTEXT_LOCAL("Bouvet Island")}}, + {267, {267, LOCTEXT_LOCAL("BW"), LOCTEXT_LOCAL("Botswana")}}, + {375, {375, LOCTEXT_LOCAL("BY"), LOCTEXT_LOCAL("Belarus")}}, + {501, {501, LOCTEXT_LOCAL("BZ"), LOCTEXT_LOCAL("Belize")}}, + {1, {1, LOCTEXT_LOCAL("CA"), LOCTEXT_LOCAL("Canada")}}, + {672, {672, LOCTEXT_LOCAL("CC"), LOCTEXT_LOCAL("Cocos (Keeling) Islands")}}, + {236, {236, LOCTEXT_LOCAL("CF"), LOCTEXT_LOCAL("Central African Republic")}}, + {242, {242, LOCTEXT_LOCAL("CG"), LOCTEXT_LOCAL("Congo")}}, + {41, {41, LOCTEXT_LOCAL("CH"), LOCTEXT_LOCAL("Switzerland")}}, + {225, {225, LOCTEXT_LOCAL("CI"), LOCTEXT_LOCAL("Cote d`Ivoire")}}, + {682, {682, LOCTEXT_LOCAL("CK"), LOCTEXT_LOCAL("Cook Islands")}}, + {56, {56, LOCTEXT_LOCAL("CL"), LOCTEXT_LOCAL("Chile")}}, + {237, {237, LOCTEXT_LOCAL("CM"), LOCTEXT_LOCAL("Cameroon")}}, + {86, {86, LOCTEXT_LOCAL("CN"), LOCTEXT_LOCAL("China")}}, + {57, {57, LOCTEXT_LOCAL("CO"), LOCTEXT_LOCAL("Colombia")}}, + {506, {506, LOCTEXT_LOCAL("CR"), LOCTEXT_LOCAL("Costa Rica")}}, + {53, {53, LOCTEXT_LOCAL("CU"), LOCTEXT_LOCAL("Cuba")}}, + {238, {238, LOCTEXT_LOCAL("CV"), LOCTEXT_LOCAL("Cape Verde")}}, + {5999, {5999, LOCTEXT_LOCAL("CW"), LOCTEXT_LOCAL("Curacao")}}, + {6189164, {6189164, LOCTEXT_LOCAL("CX"), LOCTEXT_LOCAL("Christmas Island")}}, + {357, {357, LOCTEXT_LOCAL("CY"), LOCTEXT_LOCAL("Cyprus")}}, + {420, {420, LOCTEXT_LOCAL("CZ"), LOCTEXT_LOCAL("Czechia")}}, + {49, {49, LOCTEXT_LOCAL("DE"), LOCTEXT_LOCAL("Germany")}}, + {253, {253, LOCTEXT_LOCAL("DJ"), LOCTEXT_LOCAL("Djibouti")}}, + {45, {45, LOCTEXT_LOCAL("DK"), LOCTEXT_LOCAL("Denmark")}}, + {1767, {1767, LOCTEXT_LOCAL("DM"), LOCTEXT_LOCAL("Dominica")}}, + {1809, {1809, LOCTEXT_LOCAL("DO"), LOCTEXT_LOCAL("Dominican Republic")}}, + {213, {213, LOCTEXT_LOCAL("DZ"), LOCTEXT_LOCAL("Algeria")}}, + {593, {593, LOCTEXT_LOCAL("EC"), LOCTEXT_LOCAL("Ecuador")}}, + {372, {372, LOCTEXT_LOCAL("EE"), LOCTEXT_LOCAL("Estonia")}}, + {20, {20, LOCTEXT_LOCAL("EG"), LOCTEXT_LOCAL("Egypt")}}, + {212, {212, LOCTEXT_LOCAL("EH"), LOCTEXT_LOCAL("Western Sahara")}}, + {291, {291, LOCTEXT_LOCAL("ER"), LOCTEXT_LOCAL("Eritrea")}}, + {34, {34, LOCTEXT_LOCAL("ES"), LOCTEXT_LOCAL("Spain")}}, + {251, {251, LOCTEXT_LOCAL("ET"), LOCTEXT_LOCAL("Ethiopia")}}, + {358, {358, LOCTEXT_LOCAL("FI"), LOCTEXT_LOCAL("Finland")}}, + {679, {679, LOCTEXT_LOCAL("FJ"), LOCTEXT_LOCAL("Fiji")}}, + {298, {298, LOCTEXT_LOCAL("FO"), LOCTEXT_LOCAL("Faroe Islands")}}, + {33, {33, LOCTEXT_LOCAL("FR"), LOCTEXT_LOCAL("France")}}, + {241, {241, LOCTEXT_LOCAL("GA"), LOCTEXT_LOCAL("Gabon")}}, + {44, {44, LOCTEXT_LOCAL("GB"), LOCTEXT_LOCAL("United Kingdom")}}, + {1473, {1473, LOCTEXT_LOCAL("GD"), LOCTEXT_LOCAL("Grenada")}}, + {995, {995, LOCTEXT_LOCAL("GE"), LOCTEXT_LOCAL("Georgia")}}, + {594, {594, LOCTEXT_LOCAL("GF"), LOCTEXT_LOCAL("French Guiana")}}, + {441481, {441481, LOCTEXT_LOCAL("GG"), LOCTEXT_LOCAL("Guernsey")}}, + {233, {233, LOCTEXT_LOCAL("GH"), LOCTEXT_LOCAL("Ghana")}}, + {350, {350, LOCTEXT_LOCAL("GI"), LOCTEXT_LOCAL("Gibraltar")}}, + {299, {299, LOCTEXT_LOCAL("GL"), LOCTEXT_LOCAL("Greenland")}}, + {220, {220, LOCTEXT_LOCAL("GM"), LOCTEXT_LOCAL("Gambia")}}, + {224, {224, LOCTEXT_LOCAL("GN"), LOCTEXT_LOCAL("Guinea")}}, + {590, {590, LOCTEXT_LOCAL("GP"), LOCTEXT_LOCAL("Guadeloupe")}}, + {240, {240, LOCTEXT_LOCAL("GQ"), LOCTEXT_LOCAL("Equatorial Guinea")}}, + {30, {30, LOCTEXT_LOCAL("GR"), LOCTEXT_LOCAL("Greece")}}, + {502, {502, LOCTEXT_LOCAL("GT"), LOCTEXT_LOCAL("Guatemala")}}, + {1671, {1671, LOCTEXT_LOCAL("GU"), LOCTEXT_LOCAL("Guam")}}, + {245, {245, LOCTEXT_LOCAL("GW"), LOCTEXT_LOCAL("Guinea-Bissau")}}, + {592, {592, LOCTEXT_LOCAL("GY"), LOCTEXT_LOCAL("Guyana")}}, + {504, {504, LOCTEXT_LOCAL("HN"), LOCTEXT_LOCAL("Honduras")}}, + {385, {385, LOCTEXT_LOCAL("HR"), LOCTEXT_LOCAL("Croatia")}}, + {509, {509, LOCTEXT_LOCAL("HT"), LOCTEXT_LOCAL("Haiti")}}, + {36, {36, LOCTEXT_LOCAL("HU"), LOCTEXT_LOCAL("Hungary")}}, + {62, {62, LOCTEXT_LOCAL("ID"), LOCTEXT_LOCAL("Indonesia")}}, + {353, {353, LOCTEXT_LOCAL("IE"), LOCTEXT_LOCAL("Ireland")}}, + {972, {972, LOCTEXT_LOCAL("IL"), LOCTEXT_LOCAL("Israel")}}, + {441624, {441624, LOCTEXT_LOCAL("IM"), LOCTEXT_LOCAL("Isle Of Man")}}, + {91, {91, LOCTEXT_LOCAL("IN"), LOCTEXT_LOCAL("India")}}, + {246, {246, LOCTEXT_LOCAL("IO"), LOCTEXT_LOCAL("British Indian Ocean Territory")}}, + {964, {964, LOCTEXT_LOCAL("IQ"), LOCTEXT_LOCAL("Iraq")}}, + {98, {98, LOCTEXT_LOCAL("IR"), LOCTEXT_LOCAL("Iran (Islamic Republic of)")}}, + {354, {354, LOCTEXT_LOCAL("IS"), LOCTEXT_LOCAL("Iceland")}}, + {39, {39, LOCTEXT_LOCAL("IT"), LOCTEXT_LOCAL("Italy")}}, + {441534, {441534, LOCTEXT_LOCAL("JE"), LOCTEXT_LOCAL("Jersey")}}, + {1876, {1876, LOCTEXT_LOCAL("JM"), LOCTEXT_LOCAL("Jamaica")}}, + {962, {962, LOCTEXT_LOCAL("JO"), LOCTEXT_LOCAL("Jordan")}}, + {81, {81, LOCTEXT_LOCAL("JP"), LOCTEXT_LOCAL("Japan")}}, + {254, {254, LOCTEXT_LOCAL("KE"), LOCTEXT_LOCAL("Kenya")}}, + {996, {996, LOCTEXT_LOCAL("KG"), LOCTEXT_LOCAL("Kyrgyzstan")}}, + {855, {855, LOCTEXT_LOCAL("KH"), LOCTEXT_LOCAL("Cambodia")}}, + {686, {686, LOCTEXT_LOCAL("KI"), LOCTEXT_LOCAL("Kiribati")}}, + {269, {269, LOCTEXT_LOCAL("KM"), LOCTEXT_LOCAL("Comoros")}}, + {1869, {1869, LOCTEXT_LOCAL("KN"), LOCTEXT_LOCAL("Saint Kitts and Nevis")}}, + {82, {82, LOCTEXT_LOCAL("KR"), LOCTEXT_LOCAL("Republic of Korea")}}, + {965, {965, LOCTEXT_LOCAL("KW"), LOCTEXT_LOCAL("Kuwait")}}, + {1345, {1345, LOCTEXT_LOCAL("KY"), LOCTEXT_LOCAL("Cayman Islands")}}, + {7, {7, LOCTEXT_LOCAL("KZ"), LOCTEXT_LOCAL("Kazakhstan")}}, + {961, {961, LOCTEXT_LOCAL("LB"), LOCTEXT_LOCAL("Lebanon")}}, + {1758, {1758, LOCTEXT_LOCAL("LC"), LOCTEXT_LOCAL("Saint Lucia")}}, + {423, {423, LOCTEXT_LOCAL("LI"), LOCTEXT_LOCAL("Liechtenstein")}}, + {94, {94, LOCTEXT_LOCAL("LK"), LOCTEXT_LOCAL("Sri Lanka")}}, + {231, {231, LOCTEXT_LOCAL("LR"), LOCTEXT_LOCAL("Liberia")}}, + {266, {266, LOCTEXT_LOCAL("LS"), LOCTEXT_LOCAL("Lesotho")}}, + {370, {370, LOCTEXT_LOCAL("LT"), LOCTEXT_LOCAL("Lithuania")}}, + {352, {352, LOCTEXT_LOCAL("LU"), LOCTEXT_LOCAL("Luxembourg")}}, + {371, {371, LOCTEXT_LOCAL("LV"), LOCTEXT_LOCAL("Latvia")}}, + {218, {218, LOCTEXT_LOCAL("LY"), LOCTEXT_LOCAL("Libyan Arab Jamahiriya")}}, + {212, {212, LOCTEXT_LOCAL("MA"), LOCTEXT_LOCAL("Morocco")}}, + {377, {377, LOCTEXT_LOCAL("MC"), LOCTEXT_LOCAL("Monaco")}}, + {373, {373, LOCTEXT_LOCAL("MD"), LOCTEXT_LOCAL("Moldova (Republic of)")}}, + {382, {382, LOCTEXT_LOCAL("ME"), LOCTEXT_LOCAL("Montenegro")}}, + {590, {590, LOCTEXT_LOCAL("MF"), LOCTEXT_LOCAL("Saint Martin French")}}, + {261, {261, LOCTEXT_LOCAL("MG"), LOCTEXT_LOCAL("Madagascar")}}, + {692, {692, LOCTEXT_LOCAL("MH"), LOCTEXT_LOCAL("Marshall Islands")}}, + {223, {223, LOCTEXT_LOCAL("ML"), LOCTEXT_LOCAL("Mali")}}, + {95, {95, LOCTEXT_LOCAL("MM"), LOCTEXT_LOCAL("Myanmar")}}, + {976, {976, LOCTEXT_LOCAL("MN"), LOCTEXT_LOCAL("Mongolia")}}, + {1670, {1670, LOCTEXT_LOCAL("MP"), LOCTEXT_LOCAL("Northern Mariana Islands")}}, + {596, {596, LOCTEXT_LOCAL("MQ"), LOCTEXT_LOCAL("Martinique")}}, + {222, {222, LOCTEXT_LOCAL("MR"), LOCTEXT_LOCAL("Mauritania")}}, + {1664, {1664, LOCTEXT_LOCAL("MS"), LOCTEXT_LOCAL("Montserrat")}}, + {356, {356, LOCTEXT_LOCAL("MT"), LOCTEXT_LOCAL("Malta")}}, + {230, {230, LOCTEXT_LOCAL("MU"), LOCTEXT_LOCAL("Mauritius")}}, + {960, {960, LOCTEXT_LOCAL("MV"), LOCTEXT_LOCAL("Maldives")}}, + {265, {265, LOCTEXT_LOCAL("MW"), LOCTEXT_LOCAL("Malawi")}}, + {52, {52, LOCTEXT_LOCAL("MX"), LOCTEXT_LOCAL("Mexico")}}, + {60, {60, LOCTEXT_LOCAL("MY"), LOCTEXT_LOCAL("Malaysia")}}, + {258, {258, LOCTEXT_LOCAL("MZ"), LOCTEXT_LOCAL("Mozambique")}}, + {264, {264, LOCTEXT_LOCAL("NA"), LOCTEXT_LOCAL("Namibia")}}, + {687, {687, LOCTEXT_LOCAL("NC"), LOCTEXT_LOCAL("New Caledonia")}}, + {227, {227, LOCTEXT_LOCAL("NE"), LOCTEXT_LOCAL("Niger")}}, + {672, {672, LOCTEXT_LOCAL("NF"), LOCTEXT_LOCAL("Norfolk Island")}}, + {234, {234, LOCTEXT_LOCAL("NG"), LOCTEXT_LOCAL("Nigeria")}}, + {505, {505, LOCTEXT_LOCAL("NI"), LOCTEXT_LOCAL("Nicaragua")}}, + {31, {31, LOCTEXT_LOCAL("NL"), LOCTEXT_LOCAL("Netherlands")}}, + {47, {47, LOCTEXT_LOCAL("NO"), LOCTEXT_LOCAL("Norway")}}, + {977, {977, LOCTEXT_LOCAL("NP"), LOCTEXT_LOCAL("Nepal")}}, + {674, {674, LOCTEXT_LOCAL("NR"), LOCTEXT_LOCAL("Nauru")}}, + {683, {683, LOCTEXT_LOCAL("NU"), LOCTEXT_LOCAL("Niue")}}, + {64, {64, LOCTEXT_LOCAL("NZ"), LOCTEXT_LOCAL("New Zealand")}}, + {968, {968, LOCTEXT_LOCAL("OM"), LOCTEXT_LOCAL("Oman")}}, + {507, {507, LOCTEXT_LOCAL("PA"), LOCTEXT_LOCAL("Panama")}}, + {51, {51, LOCTEXT_LOCAL("PE"), LOCTEXT_LOCAL("Peru")}}, + {689, {689, LOCTEXT_LOCAL("PF"), LOCTEXT_LOCAL("French Polynesia")}}, + {675, {675, LOCTEXT_LOCAL("PG"), LOCTEXT_LOCAL("Papua New Guinea")}}, + {63, {63, LOCTEXT_LOCAL("PH"), LOCTEXT_LOCAL("Philippines")}}, + {92, {92, LOCTEXT_LOCAL("PK"), LOCTEXT_LOCAL("Pakistan")}}, + {48, {48, LOCTEXT_LOCAL("PL"), LOCTEXT_LOCAL("Poland")}}, + {508, {508, LOCTEXT_LOCAL("PM"), LOCTEXT_LOCAL("Saint Pierre and Miquelon")}}, + {64, {64, LOCTEXT_LOCAL("PN"), LOCTEXT_LOCAL("Pitcairn")}}, + {1787, {1787, LOCTEXT_LOCAL("PR"), LOCTEXT_LOCAL("Puerto Rico")}}, + {351, {351, LOCTEXT_LOCAL("PT"), LOCTEXT_LOCAL("Portugal")}}, + {680, {680, LOCTEXT_LOCAL("PW"), LOCTEXT_LOCAL("Palau")}}, + {595, {595, LOCTEXT_LOCAL("PY"), LOCTEXT_LOCAL("Paraguay")}}, + {974, {974, LOCTEXT_LOCAL("QA"), LOCTEXT_LOCAL("Qatar")}}, + {262, {262, LOCTEXT_LOCAL("RE"), LOCTEXT_LOCAL("Reunion")}}, + {40, {40, LOCTEXT_LOCAL("RO"), LOCTEXT_LOCAL("Romania")}}, + {381, {381, LOCTEXT_LOCAL("RS"), LOCTEXT_LOCAL("Serbia")}}, + {7, {7, LOCTEXT_LOCAL("RU"), LOCTEXT_LOCAL("Russian Federation")}}, + {250, {250, LOCTEXT_LOCAL("RW"), LOCTEXT_LOCAL("Rwanda")}}, + {966, {966, LOCTEXT_LOCAL("SA"), LOCTEXT_LOCAL("Saudi Arabia")}}, + {677, {677, LOCTEXT_LOCAL("SB"), LOCTEXT_LOCAL("Solomon Islands")}}, + {248, {248, LOCTEXT_LOCAL("SC"), LOCTEXT_LOCAL("Seychelles")}}, + {249, {249, LOCTEXT_LOCAL("SD"), LOCTEXT_LOCAL("Sudan")}}, + {46, {46, LOCTEXT_LOCAL("SE"), LOCTEXT_LOCAL("Sweden")}}, + {65, {65, LOCTEXT_LOCAL("SG"), LOCTEXT_LOCAL("Singapore")}}, + {290, {290, LOCTEXT_LOCAL("SH"), LOCTEXT_LOCAL("Saint Helena")}}, + {386, {386, LOCTEXT_LOCAL("SI"), LOCTEXT_LOCAL("Slovenia")}}, + {421, {421, LOCTEXT_LOCAL("SK"), LOCTEXT_LOCAL("Slovakia")}}, + {232, {232, LOCTEXT_LOCAL("SL"), LOCTEXT_LOCAL("Sierra Leone")}}, + {378, {378, LOCTEXT_LOCAL("SM"), LOCTEXT_LOCAL("San Marino")}}, + {221, {221, LOCTEXT_LOCAL("SN"), LOCTEXT_LOCAL("Senegal")}}, + {252, {252, LOCTEXT_LOCAL("SO"), LOCTEXT_LOCAL("Somalia")}}, + {597, {597, LOCTEXT_LOCAL("SR"), LOCTEXT_LOCAL("Suriname")}}, + {211, {211, LOCTEXT_LOCAL("SS"), LOCTEXT_LOCAL("South Sudan")}}, + {239, {239, LOCTEXT_LOCAL("ST"), LOCTEXT_LOCAL("Sao Tome and Principe")}}, + {503, {503, LOCTEXT_LOCAL("SV"), LOCTEXT_LOCAL("El Salvador")}}, + {1721, {1721, LOCTEXT_LOCAL("SX"), LOCTEXT_LOCAL("Sint Maarten Dutch")}}, + {963, {963, LOCTEXT_LOCAL("SY"), LOCTEXT_LOCAL("Syrian Arab Republic")}}, + {268, {268, LOCTEXT_LOCAL("SZ"), LOCTEXT_LOCAL("Swaziland")}}, + {1649, {1649, LOCTEXT_LOCAL("TC"), LOCTEXT_LOCAL("Turks and Caicos Islands")}}, + {235, {235, LOCTEXT_LOCAL("TD"), LOCTEXT_LOCAL("Chad")}}, + {1, {1, LOCTEXT_LOCAL("TF"), LOCTEXT_LOCAL("French Southern Territories")}}, + {228, {228, LOCTEXT_LOCAL("TG"), LOCTEXT_LOCAL("Togo")}}, + {66, {66, LOCTEXT_LOCAL("TH"), LOCTEXT_LOCAL("Thailand")}}, + {992, {992, LOCTEXT_LOCAL("TJ"), LOCTEXT_LOCAL("Tajikistan")}}, + {690, {690, LOCTEXT_LOCAL("TK"), LOCTEXT_LOCAL("Tokelau")}}, + {670, {670, LOCTEXT_LOCAL("TL"), LOCTEXT_LOCAL("Timor-Leste (East Timor)")}}, + {993, {993, LOCTEXT_LOCAL("TM"), LOCTEXT_LOCAL("Turkmenistan")}}, + {216, {216, LOCTEXT_LOCAL("TN"), LOCTEXT_LOCAL("Tunisia")}}, + {676, {676, LOCTEXT_LOCAL("TO"), LOCTEXT_LOCAL("Tonga")}}, + {90, {90, LOCTEXT_LOCAL("TR"), LOCTEXT_LOCAL("Turkey")}}, + {1868, {1868, LOCTEXT_LOCAL("TT"), LOCTEXT_LOCAL("Trinidad and Tobago")}}, + {688, {688, LOCTEXT_LOCAL("TV"), LOCTEXT_LOCAL("Tuvalu")}}, + {886, {886, LOCTEXT_LOCAL("TW"), LOCTEXT_LOCAL("Taiwan (Province of China)")}}, + {255, {255, LOCTEXT_LOCAL("TZ"), LOCTEXT_LOCAL("Tanzania (United Republic of)")}}, + {380, {380, LOCTEXT_LOCAL("UA"), LOCTEXT_LOCAL("Ukraine")}}, + {256, {256, LOCTEXT_LOCAL("UG"), LOCTEXT_LOCAL("Uganda")}}, + {1, {1, LOCTEXT_LOCAL("US"), LOCTEXT_LOCAL("United States")}}, + {598, {598, LOCTEXT_LOCAL("UY"), LOCTEXT_LOCAL("Uruguay")}}, + {998, {998, LOCTEXT_LOCAL("UZ"), LOCTEXT_LOCAL("Uzbekistan")}}, + {58, {58, LOCTEXT_LOCAL("VE"), LOCTEXT_LOCAL("Venezuela")}}, + {1284, {1284, LOCTEXT_LOCAL("VG"), LOCTEXT_LOCAL("Virgin Islands British")}}, + {1340, {1340, LOCTEXT_LOCAL("VI"), LOCTEXT_LOCAL("Virgin Islands US")}}, + {84, {84, LOCTEXT_LOCAL("VN"), LOCTEXT_LOCAL("Vietnam")}}, + {678, {678, LOCTEXT_LOCAL("VU"), LOCTEXT_LOCAL("Vanuatu")}}, + {681, {681, LOCTEXT_LOCAL("WF"), LOCTEXT_LOCAL("Wallis and Futuna Islands")}}, + {685, {685, LOCTEXT_LOCAL("WS"), LOCTEXT_LOCAL("Samoa")}}, + {383, {383, LOCTEXT_LOCAL("XK"), LOCTEXT_LOCAL("Kosovo")}}, + {967, {967, LOCTEXT_LOCAL("YE"), LOCTEXT_LOCAL("Yemen")}}, + {262269, {262269, LOCTEXT_LOCAL("YT"), LOCTEXT_LOCAL("Mayotte")}}, + {38, {38, LOCTEXT_LOCAL("YU"), LOCTEXT_LOCAL("Yugoslavia")}}, + {27, {27, LOCTEXT_LOCAL("ZA"), LOCTEXT_LOCAL("South Africa")}}, + {260, {260, LOCTEXT_LOCAL("ZM"), LOCTEXT_LOCAL("Zambia")}}, + {263, {263, LOCTEXT_LOCAL("ZW"), LOCTEXT_LOCAL("Zimbabwe")}}, + }; + + static FThirdwebCountryCode GetCountryCodeData(const int32 CountryCode) { return Map.Contains(CountryCode) ? Map[CountryCode] : FThirdwebCountryCode(); } + + static TArray GetCountryCodesArray() + { + TArray CountryCodes; + Map.GenerateValueArray(CountryCodes); + return CountryCodes; + } +} +#undef LOCTEXT_LOCAL +#undef LOCTEXT_NAMESPACE diff --git a/Source/Thirdweb/Public/Thirdweb.h b/Source/Thirdweb/Public/Thirdweb.h index 7903b97..a804ce3 100644 --- a/Source/Thirdweb/Public/Thirdweb.h +++ b/Source/Thirdweb/Public/Thirdweb.h @@ -25,8 +25,6 @@ namespace Thirdweb // Assign's result to variables and then frees the underlying FFIResult bool AssignResult(FString& Output, const bool bErrorOnlyResult = false) const; - // Assign's result to variables including retry and then frees the underlying FFIResult - bool AssignRetryResult(bool& bCanRetry, FString& Output, const bool bErrorOnlyResult = false) const; // Frees the FFI Result for functions that have no relevant output void Free() const; // Convenience function to log the FFIResult @@ -83,6 +81,9 @@ namespace Thirdweb FFIResult ecosystem_wallet_sign_in_with_auth_endpoint(uintptr_t handle_id, const char* payload); FFIResult ecosystem_wallet_sign_in_with_guest(uintptr_t handle_id, const char* session_id); + FFIResult ecosystem_wallet_link_account(uintptr_t handle_id, uintptr_t wallet_to_link_handle_id, const char* otp, const char* oauth_result, const char* jwt, const char* payload); + FFIResult ecosystem_wallet_get_linked_accounts(uintptr_t handle_id); + // Smart Wallet management FFIResult create_smart_wallet(const char* client_id, diff --git a/Source/Thirdweb/Public/ThirdwebCommon.h b/Source/Thirdweb/Public/ThirdwebCommon.h index a033b7d..71ccabd 100644 --- a/Source/Thirdweb/Public/ThirdwebCommon.h +++ b/Source/Thirdweb/Public/ThirdwebCommon.h @@ -53,13 +53,6 @@ enum class EThirdwebOAuthBrowserBackend : uint8 External UMETA(DisplayName="External"), }; -UENUM() -enum class EThirdwebAuthenticationMethod : uint8 -{ - ClientID UMETA(DisplayName="Client ID"), - SecretKey UMETA(DisplayName="Secret Key"), -}; - UENUM(BlueprintType, DisplayName="OTP Method") enum class EThirdwebOTPMethod : uint8 { diff --git a/Source/Thirdweb/Public/ThirdwebFunctionLibrary.h b/Source/Thirdweb/Public/ThirdwebFunctionLibrary.h index 63f29f0..3661438 100644 --- a/Source/Thirdweb/Public/ThirdwebFunctionLibrary.h +++ b/Source/Thirdweb/Public/ThirdwebFunctionLibrary.h @@ -6,14 +6,11 @@ #include "ThirdwebFunctionLibrary.generated.h" - +struct FThirdwebCountryCode; struct FInAppWalletHandle; struct FSmartWalletHandle; enum class EFunctionResult : uint8; enum class EThirdwebOAuthProvider : uint8; -enum class EThirdwebOTPMethod : uint8; -enum class EOTPVerificationFunctionResult : uint8; -enum class ESmartWalletDeployedFunctionResult : uint8; /** * Thirdweb Function Library @@ -41,148 +38,57 @@ class THIRDWEB_API UThirdwebFunctionLibrary : public UBlueprintFunctionLibrary static bool NotEqual_SmartWalletHandleSmartWalletHandle(FSmartWalletHandle A, FSmartWalletHandle B); /** Gets the public address of an InApp wallet handle */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|Wallet") + UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|String|In App Wallet") static FString Conv_InAppWalletHandleToString(FInAppWalletHandle Wallet); /** Gets the public address of a smart wallet handle */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|Wallet") + UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|String|Smart Wallet") static FString Conv_SmartWalletHandleToString(FSmartWalletHandle Wallet); /** Gets the public address of an InApp wallet handle */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address (Text)", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|Wallet") + UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|Text|In App Wallet") static FText Conv_InAppWalletHandleToText(FInAppWalletHandle Wallet); /** Gets the public address of a smart wallet handle */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address (Text)", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|Wallet") + UFUNCTION(BlueprintPure, meta=(DisplayName="Get Address", BlueprintAutocast), Category="Utilities|Text|Smart Wallet") static FText Conv_SmartWalletHandleToText(FSmartWalletHandle Wallet); - UFUNCTION(BlueprintCallable, DisplayName="Create Email Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppEmailWallet(const FString& Email, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create OAuth Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppOAuthWallet(const EThirdwebOAuthProvider Provider, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create Phone Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppPhoneWallet(const FString& Phone, const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create JWT Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppJwtWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create Auth Endpoint Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppAuthEndpointWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create Guest Wallet", meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PartnerId"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_CreateInAppGuestWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error); - - UFUNCTION(BlueprintCallable, DisplayName="Create Smart Wallet", - meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="bGasless,Factory,AccountOverride", AutoCreateRefTerm="Factory,AccountOverride"), Category="Thirdweb|Wallets|Smart Wallet") - static EFunctionResult BP_CreateSmartWallet(const FInAppWalletHandle PersonalWallet, - FSmartWalletHandle& SmartWallet, - FString& Error, - const int64 ChainID, - const bool bGasless = true, - const FString& Factory = "", - const FString& AccountOverride = ""); - - /** Signs an arbitrary message with an InApp wallet */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Sign Message"), Category="Thirdweb|Wallets") - static FString BP_SignInAppMessage(const FInAppWalletHandle& Wallet, const FString& Message); - - /** Signs an arbitrary message with a smart wallet */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Sign Message"), Category="Thirdweb|Wallets") - static FString BP_SignSmartMessage(const FSmartWalletHandle& Wallet, const FString& Message); - /** Check if the wallet handle is connected to a session */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Connected"), Category="Thirdweb|Wallets") + UFUNCTION(BlueprintPure, meta=(DisplayName="Is Connected"), Category="Thirdweb|Wallets|In App") static bool BP_WalletIsConnected(const FInAppWalletHandle& Wallet); /** Disconnect the wallet handle from a session. Blueprint Callable for side effects */ - UFUNCTION(BlueprintCallable, meta=(DisplayName="Disconnect"), Category="Thirdweb|Wallets") + UFUNCTION(BlueprintCallable, meta=(DisplayName="Disconnect"), Category="Thirdweb|Wallets|In App") static void BP_DisconnectWallet(const FInAppWalletHandle& Wallet); - /** Verifies an OTP for the in-app wallet */ - UFUNCTION(BlueprintCallable, meta=(DisplayName="Verify OTP", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EOTPVerificationFunctionResult BP_VerifyOTP(const EThirdwebOTPMethod Method, FInAppWalletHandle Wallet, const FString& OTP, FString& Error); - - /** Sends an OTP for the in-app wallet */ - UFUNCTION(BlueprintCallable, meta=(DisplayName="Send OTP", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_SendOTP(const EThirdwebOTPMethod Method, FInAppWalletHandle Wallet, FString& Error); - // Fetch OAuth login link UFUNCTION(BlueprintCallable, meta=(DisplayName="Fetch OAuth Login Link", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") static EFunctionResult BP_FetchOAuthLoginLink(FInAppWalletHandle Wallet, const FString& RedirectUrl, FString& LoginLink, FString& Error); - - // Sign in with the oauth payload received from your login flow - UFUNCTION(BlueprintCallable, meta=(DisplayName="Sign In With OAuth", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_SignInWithOAuth(FInAppWalletHandle Wallet, const FString& AuthResult, FString& Error); - - // Sign in with the oauth payload received from your login flow - UFUNCTION(BlueprintCallable, meta=(DisplayName="Sign In With JWT", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_SignInWithJwt(FInAppWalletHandle Wallet, const FString& Jwt, FString& Error); - - // Sign in with the oauth payload received from your login flow - UFUNCTION(BlueprintCallable, meta=(DisplayName="Sign In With Auth Endpoint", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_SignInWithAuthEndpoint(FInAppWalletHandle Wallet, const FString& Payload, FString& Error); - - // Sign in with the oauth payload received from your login flow - UFUNCTION(BlueprintCallable, meta=(DisplayName="Sign In With Guest", ExpandEnumAsExecs="ReturnValue"), Category="Thirdweb|Wallets|In App") - static EFunctionResult BP_SignInWithGuest(FInAppWalletHandle Wallet, FString& Error); /** Check if an InApp wallet handle is valid */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid"), Category="Thirdweb|Wallets") + UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid"), Category="Thirdweb|Wallets|In App") static bool BP_InAppWalletIsValid(const FInAppWalletHandle& Wallet); /** Check if a smart wallet handle is valid */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid"), Category="Thirdweb|Wallets") + UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid"), Category="Thirdweb|Wallets|Smart") static bool BP_SmartWalletIsValid(const FSmartWalletHandle& Wallet); - /** Check if a smart wallet is deployed */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Is Deployed", meta=(ExpandEnumAsExecs="ReturnValue")) - static ESmartWalletDeployedFunctionResult BP_IsSmartWalletDeployed(FSmartWalletHandle Wallet, FString& Error); - - /** Create a session key for a smart wallet */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Create Session Key", - meta=(ExpandEnumAsExecs="ReturnValue", AdvancedDisplay="PermissionStart,PermissionEnd,RequestValidityStart,RequestValidityEnd", AutoCreateRefTerm= - "PermissionStart,PermissionEnd,RequestValidityStart,RequestValidityEnd,ApprovedTargets,Signer,NativeTokenLimitPerTransactionInWei")) - static EFunctionResult BP_CreateSmartWalletSessionKey(FSmartWalletHandle Wallet, - const FString& Signer, - const TArray& ApprovedTargets, - const FString& NativeTokenLimitPerTransactionInWei, - const FDateTime& PermissionStart, - const FDateTime& PermissionEnd, - const FDateTime& RequestValidityStart, - const FDateTime& RequestValidityEnd, - FString& TransactionHash, - FString& Error); - - /** Get all admins of a smart wallet */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Get Admins", meta=(ExpandEnumAsExecs="ReturnValue")) - static EFunctionResult BP_GetSmartWalletAdmins(FSmartWalletHandle Wallet, TArray& Admins, FString& Error); - - /** Get all active signers of a smart wallet */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Get Active Signers", meta=(ExpandEnumAsExecs="ReturnValue")) - static EFunctionResult BP_GetSmartWalletActiveSigners(FSmartWalletHandle Wallet, TArray& Signers, FString& Error); - - /** Revoke the session key of a smart wallet signer */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Revoke Session Key", meta=(ExpandEnumAsExecs="ReturnValue")) - static EFunctionResult BP_RevokeSmartWalletSessionKey(FSmartWalletHandle Wallet, const FString& Signer, FString& Error); - - /** Add an admin signer to a smart wallet */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Add Admin", meta=(ExpandEnumAsExecs="ReturnValue")) - static EFunctionResult BP_AddSmartWalletAdmin(FSmartWalletHandle Wallet, const FString& Signer, FString& Error); - - /** Remove an admin signer from a smart wallet */ - UFUNCTION(BlueprintCallable, Category="Thirdweb|Wallets|Smart Wallet", DisplayName="Remove Admin", meta=(ExpandEnumAsExecs="ReturnValue")) - static EFunctionResult BP_RemoveSmartWalletAdmin(FSmartWalletHandle Wallet, const FString& Signer, FString& Error); - /** Convert a Thirdweb OAuth Provider to Text */ - UFUNCTION(BlueprintPure, meta=(DisplayName="To Text", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|Text") + UFUNCTION(BlueprintPure, meta=(DisplayName="To Text (Thirdweb OAuth Provider)", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|Text") static FText Conv_ThirdwebOAuthProviderToText(EThirdwebOAuthProvider Provider); /** Convert a Thirdweb OAuth Provider to String */ - UFUNCTION(BlueprintPure, meta=(DisplayName="To String", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|String") + UFUNCTION(BlueprintPure, meta=(DisplayName="To String (Thirdweb OAuth Provider)", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|String") static FString Conv_ThirdwebOAuthProviderToString(EThirdwebOAuthProvider Provider); + /** Convert a Thirdweb OAuth Provider to Text */ + UFUNCTION(BlueprintPure, meta=(DisplayName="To Thirdweb OAuth Provider", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|Text") + static EThirdwebOAuthProvider Conv_TextToThirdwebOAuthProvider(FText Text); + + /** Convert a Thirdweb OAuth Provider to String */ + UFUNCTION(BlueprintPure, meta=(DisplayName="To Thirdweb OAuth Provider", CompactNodeTitle="->", BlueprintAutocast), Category="Utilities|String") + static EThirdwebOAuthProvider Conv_StringToThirdwebOAuthProvider(FString String); + /** Checks the validity of the address */ UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid Address"), Category="Utilities|String") static bool BP_IsStringValidAddress(const FString& Address, const bool bWithChecksum = false); @@ -196,20 +102,28 @@ class THIRDWEB_API UThirdwebFunctionLibrary : public UBlueprintFunctionLibrary static FString Conv_StringAddressToStringChecksummedAddress(const FString& Address); /** Checks the validity of the address */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid Address", AutoCreateRefTerm="Address"), Category="Utilities|Text") - static bool BP_IsTextValidAddress(const FText& Address, const bool bWithChecksum = false); + UFUNCTION(BlueprintPure, meta=(DisplayName="Is Valid Address"), Category="Utilities|Text") + static bool BP_IsTextValidAddress(const FText Address, const bool bWithChecksum = false); /** Checks the checksum of the address */ - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Checksummed Address", AutoCreateRefTerm="Address"), Category="Utilities|Text") - static bool BP_IsTextChecksummedAddress(const FText& Address); + UFUNCTION(BlueprintPure, meta=(DisplayName="Is Checksummed Address"), Category="Utilities|Text") + static bool BP_IsTextChecksummedAddress(const FText Address); /** Returns the checksummed address. If already checksummed it is a no-op */ UFUNCTION(BlueprintPure, meta=(DisplayName="To Checksummed Address", AutoCreateRefTerm="Address"), Category="Utilities|Text") static FText Conv_TextAddressToStringChecksummedAddress(const FText& Address); + /** Constant for the ethereum zero address */ UFUNCTION(BlueprintPure, meta=(DisplayName="Zero Address"), Category="Utilities|String") - static FString BP_ZeroAddress() { return TEXT("0x0000000000000000000000000000000000000000"); } + static FString BP_ZeroAddress(); + + /// Data + + /** Gets the country code data for the input country code, if it exists */ + UFUNCTION(BlueprintPure, meta=(DisplayName="Get Country Code Data"), Category="Utilities|Country Codes") + static FThirdwebCountryCode BP_GetCountryCodeData(const int32 CountryCode); - UFUNCTION(BlueprintPure, meta=(DisplayName="Is Active Signer"), Category="Utilities|String") - static bool BP_IsActiveSigner(FSmartWalletHandle Wallet, const FString& BackendWallet); + /** Gets all country code data */ + UFUNCTION(BlueprintPure, meta=(DisplayName="Get All Country Code Data"), Category="Utilities|Country Codes") + static TArray BP_GetAllCountryCodeData(); }; diff --git a/Source/Thirdweb/Public/ThirdwebMacros.h b/Source/Thirdweb/Public/ThirdwebMacros.h index 20ec4b0..1eb6334 100644 --- a/Source/Thirdweb/Public/ThirdwebMacros.h +++ b/Source/Thirdweb/Public/ThirdwebMacros.h @@ -5,4 +5,9 @@ #define TO_RUST_STRING(v) v.IsEmpty() ? nullptr : TCHAR_TO_UTF8(*v) -#define TO_RUST_TIMESTAMP(v) v == FDateTime::MinValue() ? 0 : v.ToUnixTimestamp() \ No newline at end of file +#define TO_RUST_TIMESTAMP(v) v == FDateTime::MinValue() ? 0 : v.ToUnixTimestamp() + +DECLARE_DELEGATE_OneParam(FStringDelegate, const FString&); +DECLARE_DELEGATE_OneParam(FStringArrayDelegate, const TArray&); + +DECLARE_DELEGATE_OneParam(FBoolDelegate, const bool&); \ No newline at end of file diff --git a/Source/Thirdweb/Public/ThirdwebRuntimeSettings.h b/Source/Thirdweb/Public/ThirdwebRuntimeSettings.h index eed541e..25fcd33 100644 --- a/Source/Thirdweb/Public/ThirdwebRuntimeSettings.h +++ b/Source/Thirdweb/Public/ThirdwebRuntimeSettings.h @@ -39,7 +39,7 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings FString BundleID; - /** Encryption key - Required if using custom auth methods via standard InApp wallets (Non-Ecosystem) */ + /** Required if using custom auth methods via standard InApp wallets (Non-Ecosystem) */ UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Config|InApp Wallets") FString EncryptionKey; @@ -51,10 +51,11 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Config|Ecosystem Wallets") FString EcosystemId; - /** Optional array of engine signers stored globally for convenience */ + /** Opt in or out of connect analytics */ UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category=Advanced) bool bSendAnalytics; + /** Edit Condition for overriding OAuth Browser Provider Backends */ UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category=Advanced, meta=(InlineEditConditionToggle)) bool bOverrideOAuthBrowserProviderBackends; @@ -77,16 +78,6 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings return {}; } - UFUNCTION(BlueprintPure, Category="Thirdweb|Settings") - static FString GetEncryptionKey() - { - if (const UThirdwebRuntimeSettings* Settings = Get()) - { - return Settings->EncryptionKey; - } - return TEXT(""); - } - /** Gets the first global engine signer in the array, if any */ UFUNCTION(BlueprintPure, Category="Thirdweb|Settings", meta=(ReturnDisplayName="Signers")) static FString GetThirdwebGlobalEngineSigner(bool& bFound) @@ -103,6 +94,18 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings return TEXT(""); } + /** Static accessor to get EncryptionKey */ + UFUNCTION(BlueprintPure, Category="Thirdweb|Settings") + static FString GetEncryptionKey() + { + if (const UThirdwebRuntimeSettings* Settings = Get()) + { + return Settings->EncryptionKey; + } + return TEXT(""); + } + + /** Static accessor to retrieve the absolute path of the thirdweb InAppWallet platform */ static FString GetStorageDirectory() { FString StorageDir = FPaths::Combine(IFileManager::Get().ConvertToAbsolutePathForExternalAppForWrite(*FPaths::ProjectSavedDir()), "Thirdweb", "InAppWallet"); @@ -110,6 +113,7 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings return StorageDir; } + /** Static accessor to get the resolved backend of an OAuth provider */ static bool IsExternalOAuthBackend(const EThirdwebOAuthProvider Provider) { if (const UThirdwebRuntimeSettings* Settings = Get()) @@ -123,6 +127,7 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings return false; } + /** Static accessor to get EcosystemId */ static FString GetEcosystemId() { if (const UThirdwebRuntimeSettings* Settings = Get()) @@ -132,8 +137,10 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings return TEXT(""); } + /** Static accessor to check EcosystemId validity */ static bool IsEcosystem() { return !GetEcosystemId().IsEmpty(); } + /** Static accessor to get ClientId */ static FString GetClientId() { if (const UThirdwebRuntimeSettings* Settings = Get()) @@ -142,7 +149,8 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings } return TEXT(""); } - + + /** Static accessor to get BundleId */ static FString GetBundleId() { if (const UThirdwebRuntimeSettings* Settings = Get()) @@ -151,7 +159,8 @@ class THIRDWEB_API UThirdwebRuntimeSettings : public UDeveloperSettings } return TEXT(""); } - + + /** Static accessor to check Analytics Opt-In status */ static bool AnalyticsEnabled() { if (const UThirdwebRuntimeSettings* Settings = Get()) diff --git a/Source/Thirdweb/Public/ThirdwebUtils.h b/Source/Thirdweb/Public/ThirdwebUtils.h index 5016cb3..789fac9 100644 --- a/Source/Thirdweb/Public/ThirdwebUtils.h +++ b/Source/Thirdweb/Public/ThirdwebUtils.h @@ -38,15 +38,9 @@ namespace ThirdwebUtils */ static FString ToChecksummedAddress(const FString& Address) { return Thirdweb::to_checksummed_address(TO_RUST_STRING(Address)).GetOutput(); } - /** - * Converts an EThirdwebOAuthProvider enum value to its corresponding FText representation. - * - * @param Provider The EThirdwebOAuthProvider enum value to convert. - * @return The FText representation of the specified EThirdwebOAuthProvider, or "Invalid" if the provider is not recognized. - */ - static FText ToText(const EThirdwebOAuthProvider Provider) + namespace Maps { - static TMap Map = { + static const TMap OAuthProviderToText = { {EThirdwebOAuthProvider::Google, LOCTEXT("Google", "Google")}, {EThirdwebOAuthProvider::Apple, LOCTEXT("Apple", "Apple")}, {EThirdwebOAuthProvider::Facebook, LOCTEXT("Facebook", "Facebook")}, @@ -57,7 +51,16 @@ namespace ThirdwebUtils {EThirdwebOAuthProvider::X, LOCTEXT("X", "X")}, {EThirdwebOAuthProvider::Coinbase, LOCTEXT("Coinbase", "Coinbase")} }; - return Map.Contains(Provider) ? Map[Provider] : FText::FromString(TEXT("Invalid")); + } + /** + * Converts an EThirdwebOAuthProvider enum value to its corresponding FText representation. + * + * @param Provider The EThirdwebOAuthProvider enum value to convert. + * @return The FText representation of the specified EThirdwebOAuthProvider, or "Invalid" if the provider is not recognized. + */ + static FText ToText(const EThirdwebOAuthProvider Provider) + { + return Maps::OAuthProviderToText.Contains(Provider) ? Maps::OAuthProviderToText[Provider] : FText::FromString(TEXT("Invalid")); } /** @@ -69,12 +72,31 @@ namespace ThirdwebUtils static FString ToString(const EThirdwebOAuthProvider Provider) { return ToText(Provider).ToString(); } /** - * Derives a client ID from the provided secret key. + * Converts the given FText to its corresponding EThirdwebOAuthProvider enum value. * - * @param SecretKey The secret key used to compute the client ID. - * @return The computed client ID. + * @param Text The FText representation of the OAuth provider to convert. + * @return The corresponding EThirdwebOAuthProvider enum value, or EThirdwebOAuthProvider::None if the provider is not recognized. */ - static FString GetClientIdFromSecretKey(const FString& SecretKey) { return Thirdweb::compute_client_id_from_secret_key(TO_RUST_STRING(SecretKey)).GetOutput(); } + static EThirdwebOAuthProvider ToOAuthProvider(const FText& Text) + { + for (const auto& It : Maps::OAuthProviderToText) + { + if (It.Value.EqualToCaseIgnored(Text)) + { + return It.Key; + } + } + return EThirdwebOAuthProvider::None; + } + + /** + * Converts the given FString to its corresponding EThirdwebOAuthProvider enum value. + * + * @param String The FString representation of the OAuth provider to convert. + * @return The corresponding EThirdwebOAuthProvider enum value, or EThirdwebOAuthProvider::None if the provider is not recognized. + */ + static EThirdwebOAuthProvider ToOAuthProvider(const FString& String) { return ToOAuthProvider(FText::FromString(String)); } + } #undef LOCTEXT_NAMESPACE diff --git a/Source/Thirdweb/Public/Wallets/ThirdwebInAppWalletHandle.h b/Source/Thirdweb/Public/Wallets/ThirdwebInAppWalletHandle.h index 370e8d8..5c26524 100644 --- a/Source/Thirdweb/Public/Wallets/ThirdwebInAppWalletHandle.h +++ b/Source/Thirdweb/Public/Wallets/ThirdwebInAppWalletHandle.h @@ -3,6 +3,9 @@ #pragma once #include "ThirdwebWalletHandle.h" + +#include "Engine/StreamableManager.h" + #include "ThirdwebInAppWalletHandle.generated.h" enum class EThirdwebOTPMethod : uint8; @@ -13,6 +16,9 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle { GENERATED_BODY() + DECLARE_DELEGATE_OneParam(FCreateInAppWalletDelegate, const FInAppWalletHandle&); + DECLARE_DELEGATE_OneParam(FGetLinkedAccountsDelegate, const TArray&); + enum EInAppSource { InvalidSource, @@ -35,7 +41,7 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle * @return An initialized FInAppWalletHandle instance. */ explicit FInAppWalletHandle(const EInAppSource InSource, const int64 InID); - + /** * Constructs an FInAppWalletHandle object. * @@ -75,81 +81,89 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle } /** - * Creates an in-app email wallet. + * Creates an email-based in-app wallet. * - * @param Email The email address to associate with the wallet. - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param Email The email address to associate with the wallet, must be a valid email format. + * @param SuccessDelegate Delegate to execute upon successful wallet creation. + * @param ErrorDelegate Delegate to execute upon encountering an error during wallet creation. */ - static bool CreateEmailWallet(const FString& Email, FInAppWalletHandle& Wallet, FString& Error); - static bool CreateEcosystemEmailWallet(const FString& PartnerId, const FString& Email, FInAppWalletHandle& Wallet, FString& Error); + static void CreateEmailWallet(const FString& Email, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + static void CreateEcosystemEmailWallet(const FString& PartnerId, const FString& Email, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Creates an in-app OAuth wallet using the specified provider. + * Initiates the creation of an OAuth wallet using the specified provider. * * @param Provider The OAuth provider to use for wallet creation. - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param SuccessDelegate A delegate to be called upon successful wallet creation. + * @param ErrorDelegate A delegate to be called if an error occurs during wallet creation. */ - static bool CreateOAuthWallet(const EThirdwebOAuthProvider Provider, FInAppWalletHandle& Wallet, FString& Error); - static bool CreateEcosystemOAuthWallet(const FString& PartnerId, const EThirdwebOAuthProvider Provider, FInAppWalletHandle& Wallet, FString& Error); + static void CreateOAuthWallet(const EThirdwebOAuthProvider Provider, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + static void CreateEcosystemOAuthWallet(const FString& PartnerId, const EThirdwebOAuthProvider Provider, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Creates an in-app phone wallet. + * Creates a phone-based in-app wallet. * - * @param Phone The phone number to associate with the wallet. - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param Phone The phone number used to create the wallet, which must be a valid phone number. + * @param SuccessDelegate The delegate called upon successful wallet creation. + * @param ErrorDelegate The delegate called if there is an error during wallet creation. */ - static bool CreatePhoneWallet(const FString& Phone, FInAppWalletHandle& Wallet, FString& Error); - static bool CreateEcosystemPhoneWallet(const FString& PartnerId, const FString& Phone, FInAppWalletHandle& Wallet, FString& Error); + static void CreatePhoneWallet(const FString& Phone, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + static void CreateEcosystemPhoneWallet(const FString& PartnerId, const FString& Phone, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Creates an in-app JWT wallet. + * Creates a JWT wallet. * - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param SuccessDelegate The delegate to be executed upon successful wallet creation. + * @param ErrorDelegate The delegate to be executed if an error occurs during wallet creation. */ - static bool CreateJwtWallet(FInAppWalletHandle& Wallet, FString& Error) { return CreateCustomAuthWallet(Jwt, Wallet, Error); } - static bool CreateEcosystemJwtWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) { return CreateEcosystemCustomAuthWallet(PartnerId, Jwt, Wallet, Error); } + static void CreateJwtWallet(const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { return CreateCustomAuthWallet(Jwt, SuccessDelegate, ErrorDelegate); } + + static void CreateEcosystemJwtWallet(const FString& PartnerId, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) + { + return CreateEcosystemCustomAuthWallet(PartnerId, Jwt, SuccessDelegate, ErrorDelegate); + } + /** - * Creates an in-app wallet using an authentication endpoint. + * Creates an in-app wallet with an authentication endpoint. * - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param SuccessDelegate Delegate to be called upon successful wallet creation, receiving specific success details. + * @param ErrorDelegate Delegate to be called upon an error during wallet creation, receiving the error message. */ - static bool CreateAuthEndpointWallet(FInAppWalletHandle& Wallet, FString& Error) { return CreateCustomAuthWallet(AuthEndpoint, Wallet, Error); } - static bool CreateEcosystemAuthEndpointWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) { return CreateEcosystemCustomAuthWallet(PartnerId, AuthEndpoint, Wallet, Error); } + static void CreateAuthEndpointWallet(const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) + { + return CreateCustomAuthWallet(AuthEndpoint, SuccessDelegate, ErrorDelegate); + } + + static void CreateEcosystemAuthEndpointWallet(const FString& PartnerId, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) + { + return CreateEcosystemCustomAuthWallet(PartnerId, AuthEndpoint, SuccessDelegate, ErrorDelegate); + } /** - * Creates an in-app guest wallet. + * Creates a guest wallet by delegating to the custom authorization wallet creation function. * - * @param Wallet An output parameter that will hold the newly created wallet handle if the creation is successful. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the wallet creation is successful, false otherwise. + * @param SuccessDelegate Delegate to be called upon successful wallet creation. + * @param ErrorDelegate Delegate to be called if there is an error during the wallet creation process. */ - static bool CreateGuestWallet(FInAppWalletHandle& Wallet, FString& Error) { return CreateCustomAuthWallet(Guest, Wallet, Error); } - static bool CreateEcosystemGuestWallet(const FString& PartnerId, FInAppWalletHandle& Wallet, FString& Error) { return CreateEcosystemCustomAuthWallet(PartnerId, Guest, Wallet, Error); } + static void CreateGuestWallet(const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) { return CreateCustomAuthWallet(Guest, SuccessDelegate, ErrorDelegate); } + + static void CreateEcosystemGuestWallet(const FString& PartnerId, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) + { + return CreateEcosystemCustomAuthWallet(PartnerId, Guest, SuccessDelegate, ErrorDelegate); + } private: /** * Creates a custom authenticated in-app wallet. * - * @param Source The source of authentication. The valid values are Jwt, AuthEndpoint, and Guest. - * @param Wallet Reference to an FInAppWalletHandle object that will be initialized if authentication succeeds. - * @param Error Reference to an FString that will contain an error message if authentication fails. - * @return True if the wallet is successfully created; otherwise, false. + * @param Source The source from where the in-app wallet is to be created. + * @param SuccessDelegate Delegate to be called upon successful creation of the wallet. + * @param ErrorDelegate Delegate to be called if an error occurs during the wallet creation. */ - static bool CreateCustomAuthWallet(const EInAppSource Source, FInAppWalletHandle& Wallet, FString& Error); - static bool CreateEcosystemCustomAuthWallet(const FString& PartnerId, const EInAppSource Source, FInAppWalletHandle& Wallet, FString& Error); - -public: + static void CreateCustomAuthWallet(const EInAppSource Source, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + static void CreateEcosystemCustomAuthWallet(const FString& PartnerId, const EInAppSource Source, const FCreateInAppWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); +public: /** Check if the wallet is connected to a session */ bool IsConnected() const; @@ -157,23 +171,32 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle void Disconnect() const; /** - * Verifies a One Time Password (OTP) for the in-app wallet handle. + * Sends a one-time password (OTP) to the wallet handle's associated phone or email. + * + * @param SuccessDelegate Delegate to be executed on successful OTP sending. + * @param ErrorDelegate Delegate to be executed if an error occurs during OTP sending. * - * @param Method The method by which the OTP was sent (e.g., Phone, Email). - * @param OTP The One Time Password to verify. - * @param Error Output parameter that will contain an error message if the verification fails. - * @return True if the OTP is successfully verified, false otherwise. */ - bool VerifyOTP(const EThirdwebOTPMethod Method, const FString& OTP, FString& Error); + void SendOTP(const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Signs in with a One-Time Password (OTP) for the in-app wallet handle. + * + * @param OTP The one-time password to be verified. + * @param SuccessDelegate The delegate to execute upon successful verification. + * @param ErrorDelegate The delegate to execute if verification fails or an error occurs. + */ + void SignInWithOTP(const FString& OTP, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Sends a One-Time Password (OTP) via the specified method (Phone or Email). + * Links a One-Time Password (OTP) to the specified in-app wallet. * - * @param Method The method to be used for sending the OTP (Phone or Email). - * @param Error Returns an error message if the OTP sending fails. - * @return True if the OTP was sent successfully, false otherwise. + * @param Wallet The in-app wallet handle to which the OTP will be linked. + * @param OTP The one-time password that will be linked to the wallet. + * @param SuccessDelegate The delegate to be called upon successful linking of the OTP. + * @param ErrorDelegate The delegate to be called if there is an error linking the OTP. */ - bool SendOTP(const EThirdwebOTPMethod Method, FString& Error); + void LinkOTP(const FInAppWalletHandle& Wallet, const FString& OTP, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** * Fetches the OAuth login URL for the in-app wallet. @@ -186,41 +209,94 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle bool FetchOAuthLoginURL(const FString& RedirectUrl, FString& LoginLink, FString& Error); /** - * Signs in using OAuth authentication details. + * Sign in with OAuth for the in-app wallet handle. + * + * @param AuthResult The result string obtained from OAuth authentication. + * @param SuccessDelegate Delegate to be executed upon successful sign-in. + * @param ErrorDelegate Delegate to be executed upon failure, with an error message. + */ + void SignInWithOAuth(const FString& AuthResult, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Links a new OAuth wallet to the existing in-app wallet. * - * @param AuthResult The authentication result string obtained from the OAuth provider. - * @param Error Will contain an error message if the sign-in process fails. - * @return True if sign-in was successful, false otherwise. + * @param Wallet The in-app wallet handle that the OAuth account will link with. Must be a valid handle. Must never have independently authenticated. + * @param AuthResult The authentication result string containing the OAuth credentials. + * @param SuccessDelegate A delegate that will be called upon successfully linking the OAuth account. + * @param ErrorDelegate A delegate that will be called if there is an error during the linking process, providing an error message. */ - bool SignInWithOAuth(const FString& AuthResult, FString& Error); + void LinkOAuth(const FInAppWalletHandle& Wallet, const FString& AuthResult, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Signs in using a JSON Web Token (JWT) and an encryption key. + * Signs in with a JSON Web Token (JWT) for authentication. * - * @param Jwt The JSON Web Token post-authenticating the user. This is any OIDC compatible JWT. The token should be a string starting with ey. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the sign-in is successful, false otherwise. + * @param Jwt The JSON Web Token used for authentication; must be a valid JWT string. + * @param SuccessDelegate Delegate to be executed upon successful authentication, must be bound. + * @param ErrorDelegate Delegate to be executed if an error occurs during authentication. */ - bool SignInWithJwt(const FString& Jwt, FString& Error); + void SignInWithJwt(const FString& Jwt, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Signs in using any payload. + * Links a JSON Web Token (JWT) for authentication. + * + * @param Wallet The in-app wallet handle that the JWT account will link with. Must be a valid handle. Must never have independently authenticated. + * @param Jwt The JSON Web Token used for authentication; must be a valid JWT string. + * @param SuccessDelegate Delegate to be executed upon successful authentication, must be bound. + * @param ErrorDelegate Delegate to be executed if an error occurs during authentication. + */ + void LinkJwt(const FInAppWalletHandle& Wallet, const FString& Jwt, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Signs in with the authentication endpoint using the provided payload. * - * @param Payload The data payload required for the sign-in process. The payload can have any shape, but is generally JSON. - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the sign-in is successful, false otherwise. + * @param Payload The authentication payload, must be a valid JSON string. + * @param SuccessDelegate The delegate to be executed on successful sign-in, must be bound. + * @param ErrorDelegate The delegate to be executed if an error occurs, should be bound to handle error messages. */ - bool SignInWithAuthEndpoint(const FString& Payload, FString& Error); + void SignInWithAuthEndpoint(const FString& Payload, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** - * Signs in as an anonymous guest user using a semi-reproducible device fingerprint. - * Fingerprints can change from update to update and should not be relied upon for long term use. + * links an authentication endpoint using the provided payload. + * + * @param Wallet The in-app wallet handle that the AuthEndpoint account will link with. Must be a valid handle. Must never have independently authenticated. + * @param Payload The authentication payload, must be a valid JSON string. + * @param SuccessDelegate The delegate to be executed on successful sign-in, must be bound. + * @param ErrorDelegate The delegate to be executed if an error occurs, should be bound to handle error messages. + */ + void LinkAuthEndpoint(const FInAppWalletHandle& Wallet, const FString& Payload, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Signs in with guest authentication. * - * @param Error An output parameter that will hold any error message in case of a failure. - * @return True if the sign-in is successful, false otherwise. + * @param SuccessDelegate The delegate to execute on successful sign-in. + * @param ErrorDelegate The delegate to execute if an error occurs during the sign-in process; will receive an error message. */ - bool SignInWithGuest(FString& Error); + void SignInWithGuest(const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + /** + * Links guest authentication. + * + * @param Wallet The in-app wallet handle that the guest account will link with. Must be a valid handle. Must never have independently authenticated. + * @param SuccessDelegate The delegate to execute on successful sign-in. + * @param ErrorDelegate The delegate to execute if an error occurs during the sign-in process; will receive an error message. + */ + void LinkGuest(const FInAppWalletHandle& Wallet, const FStreamableDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Retrieves the linked accounts associated with this FInAppWalletHandle. + * + * @param SuccessDelegate Delegate that will be executed with the linked accounts information if the operation is successful. + * @param ErrorDelegate Delegate that will be executed with an error message if the operation fails. + */ + void GetLinkedAccounts(const FGetLinkedAccountsDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); + + /** + * Retrieves the source of the in-app wallet. + * + * @return The source of the in-app wallet as an EInAppSource enum. + */ + EInAppSource GetSource() const { return Source; } + /** * Retrieves the source string. * @@ -258,9 +334,9 @@ struct THIRDWEB_API FInAppWalletHandle : public FWalletHandle virtual FString GetDisplayName() const override; /** - * Retrieves the current OAuth provider. + * Retrieves the configured OAuth provider. * - * @return The current OAuth provider. + * @return The configured OAuth provider. */ EThirdwebOAuthProvider GetOAuthProvider() const { return Provider; } diff --git a/Source/Thirdweb/Public/Wallets/ThirdwebSmartWalletHandle.h b/Source/Thirdweb/Public/Wallets/ThirdwebSmartWalletHandle.h index 8ee05ba..eaea2f4 100644 --- a/Source/Thirdweb/Public/Wallets/ThirdwebSmartWalletHandle.h +++ b/Source/Thirdweb/Public/Wallets/ThirdwebSmartWalletHandle.h @@ -13,6 +13,9 @@ struct THIRDWEB_API FSmartWalletHandle : public FWalletHandle { GENERATED_BODY() + DECLARE_DELEGATE_OneParam(FCreateSmartWalletDelegate, const FSmartWalletHandle&); + DECLARE_DELEGATE_OneParam(FGetActiveSignersDelegate, const TArray&); + FSmartWalletHandle() { Type = Smart; @@ -40,24 +43,23 @@ struct THIRDWEB_API FSmartWalletHandle : public FWalletHandle } /** - * Creates a new FSmartWalletHandle instance. + * Create a smart wallet handle. * - * @param ChainID The ID of the blockchain to connect to. - * @param InInAppWallet The InApp Wallet signer. - * @param bGasless A boolean indicating if the wallet should operate without gas fees. - * @param Factory The factory contract address for wallet creation. - * @param AccountOverride Optional account address to override the default. - * @param bSuccess Output parameter that will be set to true if the wallet creation is successful, false otherwise. - * @param Error Output parameter that will hold the error message if the creation fails. - * @return A new instance of FSmartWalletHandle. + * @param InInAppWallet Reference to an in-app wallet handle. + * @param ChainID Identifier of the blockchain. + * @param bGasless Boolean indicating whether the transaction is gasless. + * @param Factory String identifying the factory contract. + * @param AccountOverride String for account override. + * @param SuccessDelegate Delegate to call upon successful creation of the smart wallet. + * @param ErrorDelegate Delegate to call if there is an error during creation. */ - static FSmartWalletHandle Create(const FInAppWalletHandle& InInAppWallet, const int64 ChainID, const bool bGasless, const FString& Factory, const FString& AccountOverride, bool& bSuccess, FString& Error); + static void Create(const FInAppWalletHandle& InInAppWallet, const int64 ChainID, const bool bGasless, const FString& Factory, const FString& AccountOverride, const FCreateSmartWalletDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Check if the smart wallet is deployed */ - bool IsDeployed(bool& bDeployed, FString& Error); + void IsDeployed(const FBoolDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Create a session key for a smart wallet */ - bool CreateSessionKey( + void CreateSessionKey( const FString& Signer, const TArray& ApprovedTargets, const FString& NativeTokenLimitPerTransactionInWei, @@ -65,24 +67,24 @@ struct THIRDWEB_API FSmartWalletHandle : public FWalletHandle const FDateTime& PermissionEnd, const FDateTime& RequestValidityStart, const FDateTime& RequestValidityEnd, - FString& TransactionHash, - FString& Error + const FStringDelegate& SuccessDelegate, + const FStringDelegate& ErrorDelegate ); /** Revoke a session key for a smart wallet */ - bool RevokeSessionKey(const FString& Signer, FString& Error); + void RevokeSessionKey(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Get the admins of a smart wallet */ - bool GetAdmins(TArray& Admins, FString& Error); + void GetAdmins(const FStringArrayDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Add an admin to a smart wallet */ - bool AddAdmin(const FString& Signer, FString& Error); + void AddAdmin(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Remove an admin from a smart wallet */ - bool RemoveAdmin(const FString& Signer, FString& Error); + void RemoveAdmin(const FString& Signer, const FSimpleDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); /** Get the active signers of a smart wallet */ - bool GetActiveSigners(TArray& Signers, FString& Error); + void GetActiveSigners(const FGetActiveSignersDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate); private: FInAppWalletHandle InAppWallet; diff --git a/Source/Thirdweb/Public/Wallets/ThirdwebWalletHandle.h b/Source/Thirdweb/Public/Wallets/ThirdwebWalletHandle.h index 2e935c5..1474ccd 100644 --- a/Source/Thirdweb/Public/Wallets/ThirdwebWalletHandle.h +++ b/Source/Thirdweb/Public/Wallets/ThirdwebWalletHandle.h @@ -2,8 +2,35 @@ #pragma once +#include "ThirdwebMacros.h" #include "ThirdwebWalletHandle.generated.h" +#define CHECK_DELEGATES(SuccessDelegate, ErrorDelegate) \ + if (!SuccessDelegate.IsBound()) \ + { \ + if (ErrorDelegate.IsBound()) \ + { \ + TW_LOG(Error, TEXT("No SuccessDelegate bound::%s"), UE_SOURCE_LOCATION) \ + ErrorDelegate.Execute(TEXT("Success Delegate Not Bound")); \ + } \ + return; \ + } \ + if (!ErrorDelegate.IsBound()) { \ + TW_LOG(Error, TEXT("No ErrorDelegate bound::%s"), UE_SOURCE_LOCATION) \ + return; \ + } + +#define CHECK_VALIDITY(ErrorDelegate) \ + if (!IsValid()) \ + { \ + TW_LOG(Error, TEXT("Invalid wallet handle")) \ + if (ErrorDelegate.IsBound()) \ + { \ + ErrorDelegate.Execute(TEXT("Invalid wallet handle")); \ + } \ + return; \ + } + USTRUCT() struct THIRDWEB_API FWalletHandle { @@ -22,31 +49,68 @@ struct THIRDWEB_API FWalletHandle { } - /** True if this handle was ever initialized */ + /** + * Checks if the wallet handle is valid. + * + * @return True if the wallet handle is valid, i.e., its type is not invalid and its ID is not zero. + */ virtual bool IsValid() const { return Type != InvalidHandle && ID != 0; } - /** Explicitly clear handle */ + /** + * Invalidates the wallet handle, setting its ID to zero and marking its type as invalid. + */ virtual void Invalidate() { ID = 0; Type = InvalidHandle; } - /** Get the public address of the current wallet */ + /** + * Retrieves the wallet address associated with this handle. + * + * @return The wallet address as a string. Returns a zero address if the handle is invalid. + */ virtual FString ToAddress() const; - /** sign a message */ - virtual FString Sign(const FString& Message) const; - + /** + * Signs a given message using the wallet handle. + * + * @param Message The message to be signed. + * @param SuccessDelegate Delegate that gets called upon a successful signing operation. + * @param ErrorDelegate Delegate that gets called if an error occurs during the signing operation. + */ + virtual void Sign(const FString& Message, const FStringDelegate& SuccessDelegate, const FStringDelegate& ErrorDelegate) const; + + /** + * Get the type of wallet handle. + * @return The type of the current wallet handle. + */ EWalletHandleType GetType() const { return Type; } + /** + * Gets the ID of the wallet handle. + * + * @return The ID of the wallet handle as an int64. + */ int64 GetID() const { return ID; } + /** + * Retrieves the debug display name of the wallet handle. + * + * @return A string representing the display name of the wallet handle. + * If the wallet handle is valid, the name includes the type of the wallet and its ID. + * Returns "INVALID" if the wallet handle is not valid. + */ virtual FString GetDisplayName() const { return IsValid() ? FString::Printf(TEXT("%sWallet::%lld"), GetTypeString(), ID) : TEXT("INVALID"); } + /** + * Retrieves the type of the wallet handle as a string. + * + * @return A string representing the type of the wallet handle. Possible values are "inApp", "smart", or "invalid". + */ const TCHAR* GetTypeString() const { return Type == InApp ? TEXT("inApp") : Type == Smart ? TEXT("smart") : TEXT("invalid"); diff --git a/Source/ThirdwebEditor/ThirdwebEditor.Build.cs b/Source/ThirdwebEditor/ThirdwebEditor.Build.cs index 2a0051d..a3e2244 100644 --- a/Source/ThirdwebEditor/ThirdwebEditor.Build.cs +++ b/Source/ThirdwebEditor/ThirdwebEditor.Build.cs @@ -10,53 +10,26 @@ public ThirdwebEditor(ReadOnlyTargetRules Target) : base(Target) #if UE_5_3_OR_LATER IncludeOrderVersion = EngineIncludeOrderVersion.Latest; #endif - PublicIncludePaths.AddRange( - new string[] { - // ... add public include paths required here ... - } - ); - - - PrivateIncludePaths.AddRange( - new string[] { - // ... add other private include paths required here ... - } - ); - - - PublicDependencyModuleNames.AddRange( - new string[] - { - "Core", - "Thirdweb", - "DeveloperSettings" - // ... add other public dependencies that you statically link with here ... - } - ); - - - PrivateDependencyModuleNames.AddRange( - new string[] - { - "Projects", - "InputCore", - "EditorFramework", - "UnrealEd", - "ToolMenus", - "CoreUObject", - "Engine", - "Slate", - "SlateCore", - // ... add private dependencies that you statically link with here ... - } - ); - - - DynamicallyLoadedModuleNames.AddRange( - new string[] - { - // ... add any modules that your module loads dynamically here ... - } - ); + + PublicDependencyModuleNames.AddRange(new[] + { + "Core", + "Thirdweb", + "DeveloperSettings" + }); + + + PrivateDependencyModuleNames.AddRange(new[] + { + "Projects", + "InputCore", + "EditorFramework", + "UnrealEd", + "ToolMenus", + "CoreUObject", + "Engine", + "Slate", + "SlateCore" + }); } -} +} \ No newline at end of file diff --git a/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebBaseAsyncTask.cpp b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebBaseAsyncTask.cpp new file mode 100644 index 0000000..3607525 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebBaseAsyncTask.cpp @@ -0,0 +1,229 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "K2Node/K2Node_ThirdwebBaseAsyncTask.h" + +#include "BlueprintActionDatabaseRegistrar.h" +#include "BlueprintNodeSpawner.h" + +#include "Kismet/BlueprintAsyncActionBase.h" + +namespace TwPins +{ + const FName Provider = FName(TEXT("Provider")); + const FName Input = FName(TEXT("Input")); + const FName PartnerId = FName(TEXT("PartnerId")); + const FName Wallet = FName(TEXT("Wallet")); + const FName InAppWallet = FName(TEXT("InAppWallet")); + const FName SmartWallet = FName(TEXT("SmartWallet")); + const FName Success = FName(TEXT("Success")); + const FName Failed = FName(TEXT("Failed")); + const FName Error = FName(TEXT("Error")); +} + +#define LOCTEXT_NAMESPACE "ThirdwebUncookedOnly" + +UK2Node_ThirdwebBaseAsyncTask::UK2Node_ThirdwebBaseAsyncTask() +{ + ProxyActivateFunctionName = GET_FUNCTION_NAME_CHECKED(UBlueprintAsyncActionBase, Activate); +} + +FLinearColor UK2Node_ThirdwebBaseAsyncTask::GetNodeTitleColor() const +{ + return FLinearColor(FColor::FromHex(TEXT("#7207b9"))); +} + +FSlateIcon UK2Node_ThirdwebBaseAsyncTask::GetIconAndTint(FLinearColor& OutColor) const +{ + OutColor = FLinearColor(FColor::FromHex(TEXT("#f213a4"))); + static const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "Kismet.AllClasses.FunctionIcon");; + return Icon; +} + +void UK2Node_ThirdwebBaseAsyncTask::PinDefaultValueChanged(UEdGraphPin* Pin) +{ + Super::PinDefaultValueChanged(Pin); + UpdatePins(); +} + +FText UK2Node_ThirdwebBaseAsyncTask::GetMenuCategory() const +{ + return LOCTEXT("K2Node_ThirdwebCreateWallet_Category", "Thirdweb|Wallets"); +} + +void UK2Node_ThirdwebBaseAsyncTask::PostReconstructNode() +{ + Super::PostReconstructNode(); + UpdatePins(); +} + +void UK2Node_ThirdwebBaseAsyncTask::NotifyPinConnectionListChanged(UEdGraphPin* Pin) +{ + Super::NotifyPinConnectionListChanged(Pin); + UpdatePins(); +} + +void UK2Node_ThirdwebBaseAsyncTask::AllocateDefaultPins() +{ + // Execution pins + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute); + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then); + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, TwPins::Success); + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, TwPins::Failed); +} + +void UK2Node_ThirdwebBaseAsyncTask::PostAllocateDefaultPins() +{ + // Error Output Pin + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_String, TwPins::Error); + + UpdatePins(); +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::SetPinVisibility(UEdGraphPin* Pin, const bool bShow) +{ + if (Pin) + { + Pin->bHidden = !bShow; + } + return Pin; +} + + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::SetPinFriendlyName(UEdGraphPin* Pin, const FText& FriendlyName) +{ + if (Pin) + { + Pin->PinFriendlyName = FriendlyName; + } + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::SetPinConnectable(UEdGraphPin* Pin, const bool bConnectable) +{ + if (Pin) + { + Pin->bNotConnectable = !bConnectable; + } + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::SetPinAdvancedView(UEdGraphPin* Pin, const bool bAdvanced) +{ + if (Pin) + { + Pin->bAdvancedView = bAdvanced; + } + return Pin; +} + +void UK2Node_ThirdwebBaseAsyncTask::RemoveHiddenPins(UK2Node* K2Node) +{ + TArray Pins = K2Node->Pins; + for (int i = 0; i < Pins.Num(); i++) + { + if (UEdGraphPin* Pin = Pins[i]; Pin && Pin->bHidden) + { + UE_LOG(LogTemp, Log, TEXT("K2NodeUtils::DestroyHidden::Destroying unused pin %s"), *Pin->PinName.ToString()) + K2Node->RemovePin(Pin); + } + } +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetConnectedPin(UEdGraphPin* Pin) +{ + return Pin && Pin->LinkedTo.Num() > 0 ? Pin->LinkedTo[0] : nullptr; +} + +FString UK2Node_ThirdwebBaseAsyncTask::ResolvePinValue(UEdGraphPin* Pin) +{ + return Pin ? Pin->LinkedTo.Num() > 0 ? Pin->LinkedTo[0]->DefaultValue : Pin->DefaultValue : FString(); +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::SetPinDefaultValue(UEdGraphPin* Pin, const FString& Value) +{ + if (Pin) + { + GetDefault()->SetPinAutogeneratedDefaultValue(Pin, Value); + } + return Pin; +} + +void UK2Node_ThirdwebBaseAsyncTask::SetNodeHasAdvanced(const bool bHasAdvanced) +{ + if (bHasAdvanced) + { + if (AdvancedPinDisplay == ENodeAdvancedPins::NoPins) + { + AdvancedPinDisplay = ENodeAdvancedPins::Hidden; + } + } + else + { + AdvancedPinDisplay = ENodeAdvancedPins::NoPins; + } +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetProviderPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Provider); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetInputPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Input); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetPartnerIdPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::PartnerId); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetWalletPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Wallet); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetInAppWalletPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::InAppWallet); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetSmartWalletPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::SmartWallet); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetSuccessPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Success); + check(Pin == NULL || Pin->Direction == EGPD_Output); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetFailedPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Failed); + check(Pin == NULL || Pin->Direction == EGPD_Output); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebBaseAsyncTask::GetErrorPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Error); + check(Pin == NULL || Pin->Direction == EGPD_Output); + return Pin; +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebCreateWallet.cpp b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebCreateWallet.cpp new file mode 100644 index 0000000..6828dfc --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebCreateWallet.cpp @@ -0,0 +1,324 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "K2Node/K2Node_ThirdwebCreateWallet.h" + +#include "BlueprintActionDatabaseRegistrar.h" +#include "BlueprintNodeSpawner.h" +#include "K2Node_CallFunction.h" +#include "KismetCompiler.h" +#include "ThirdwebRuntimeSettings.h" +#include "TWUOCommon.h" +#include "TWUOUtils.h" + +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateAuthEndpointWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateEmailWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateGuestWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateJwtWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateOAuthWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreatePhoneWallet.h" +#include "AsyncTasks/Wallets/InApp/Create/AsyncTaskThirdwebCreateSmartWallet.h" + +#include "Styling/SlateIconFinder.h" + +#include "Wallets/ThirdwebInAppWalletHandle.h" +#include "Wallets/ThirdwebSmartWalletHandle.h" + +namespace TwPins +{ + const FName Type = FName(TEXT("Type")); + const FName Source = FName(TEXT("Source")); + const FName ChainID = FName(TEXT("ChainID")); + const FName Gasless = FName(TEXT("bGasless")); + const FName Factory = FName(TEXT("Factory")); + const FName AccountOverride = FName(TEXT("AccountOverride")); +} + +#define LOCTEXT_NAMESPACE "ThirdwebUncookedOnly" + +UK2Node_ThirdwebCreateWallet::UK2Node_ThirdwebCreateWallet() +{ + ProxyClass = UAsyncTaskThirdwebCreateOAuthWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateOAuthWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateOAuthWallet, CreateOAuthWallet); +} + +FText UK2Node_ThirdwebCreateWallet::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + if (TitleType == ENodeTitleType::MenuTitle) + { + return LOCTEXT("K2Node_ThirdwebCreateWallet_SmartNodeTitle", "Create Wallet"); + } + if (CachedNodeTitle.IsOutOfDate(this)) + { + CachedNodeTitle.MarkDirty(); + + if (UEdGraphPin* TypePin = GetTypePin()) + { + if (ResolvePinValue(TypePin) == TEXT("Smart")) + { + CachedNodeTitle.SetCachedText(LOCTEXT("K2Node_ThirdwebCreateWallet_SmartNodeTitle", "Create Smart Wallet"), this); + } + else + { + if (FString Source = ResolvePinValue(GetSourcePin()); Source == TEXT("OAuth") || Source == TEXT("Email") || Source == TEXT("Phone")) + { + if (Source == TEXT("OAuth")) + { + CachedNodeTitle.SetCachedText( + FText::Format(LOCTEXT("K2Node_ThirdwebCreateWallet_OAuthNodeTitle", "Create In App {0} OAuth Wallet"), FText::FromString(ResolvePinValue(GetProviderPin()))), + this + ); + } + else + { + CachedNodeTitle.SetCachedText( + FText::Format(LOCTEXT("K2Node_ThirdwebCreateWallet_OTPNodeTitle", "Create In App {0} OTP Wallet"), FText::FromString(Source)), + this + ); + } + } + else + { + CachedNodeTitle.SetCachedText( + FText::Format(LOCTEXT("K2Node_ThirdwebCreateWallet_OTPNodeTitle", "Create In App {0} Wallet"), FText::FromString(Source)), + this + ); + } + } + } + } + return CachedNodeTitle; +} + +FText UK2Node_ThirdwebCreateWallet::GetTooltipText() const +{ + return LOCTEXT("K2Node_ThirdwebCreateWallet_TooltipText", "Create a Thirdweb Wallet"); +} + +void UK2Node_ThirdwebCreateWallet::PinDefaultValueChanged(UEdGraphPin* Pin) +{ + Super::Super::PinDefaultValueChanged(Pin); + if (Pin == GetTypePin() || Pin == GetSourcePin() || Pin == GetProviderPin()) + { + CachedNodeTitle.MarkDirty(); + if (Pin == GetTypePin()) + { + for (UEdGraphPin* P : Pins) + { + if (P->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec && P->PinName != TwPins::Error) + { + P->BreakAllPinLinks(); + } + } + } + } + UpdatePins(); +} + +void UK2Node_ThirdwebCreateWallet::AllocateDefaultPins() +{ + Super::AllocateDefaultPins(); + + // Base Selector Pin + SetPinConnectable( + SetPinFriendlyName( + SetPinDefaultValue( + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, StaticEnum(), TwPins::Type), + TEXT("InApp") + ), + LOCTEXT("K2Node_ThirdwebCreateWallet_ThirdwebWalletType", "Kind") + ) + ); + + // In App Wallet Input Pins + SetPinConnectable( + SetPinDefaultValue( + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, StaticEnum(), TwPins::Source), + TEXT("OAuth") + ) + ); + + SetPinDefaultValue( + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, StaticEnum(), TwPins::Provider), + TEXT("Google") + ); + + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::Input); + + // In App Wallet Output Pins + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Struct, FInAppWalletHandle::StaticStruct(), TwPins::Wallet); + + // Smart Wallet Input Pins + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Struct, FInAppWalletHandle::StaticStruct(), TwPins::InAppWallet); + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Int64, TwPins::ChainID); + SetPinDefaultValue(CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Boolean, TwPins::Gasless), TEXT("true")); + SetPinAdvancedView(CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::Factory)); + SetPinAdvancedView(CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::AccountOverride)); + + // Smart Wallet Output Pins + SetPinFriendlyName( + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Struct, FSmartWalletHandle::StaticStruct(), TwPins::SmartWallet), + LOCTEXT("K2Node_ThirdwebCreateWallet_ThirdwebSmartWalletOutput", "Wallet") + ); + + // Ecosystem Input Pin + SetPinAdvancedView(SetPinVisibility(CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::PartnerId), true)); + + PostAllocateDefaultPins(); +} + +void UK2Node_ThirdwebCreateWallet::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) +{ + bool bSmart = ResolvePinValue(GetTypePin()) == TEXT("Smart"); + if (bSmart) + { + ProxyClass = UAsyncTaskThirdwebCreateSmartWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateSmartWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateSmartWallet, CreateSmartWallet); + } + else + { + switch (ThirdwebUtils::ToInAppWalletSource(ResolvePinValue(GetSourcePin()))) + { + case EThirdwebInAppWalletSource::OAuth: + { + ProxyClass = UAsyncTaskThirdwebCreateOAuthWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateOAuthWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateOAuthWallet, CreateOAuthWallet); + break; + } + case EThirdwebInAppWalletSource::Email: + { + ProxyClass = UAsyncTaskThirdwebCreateEmailWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateEmailWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateEmailWallet, CreateEmailWallet); + break; + } + case EThirdwebInAppWalletSource::Phone: + { + ProxyClass = UAsyncTaskThirdwebCreatePhoneWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreatePhoneWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreatePhoneWallet, CreatePhoneWallet); + break; + } + case EThirdwebInAppWalletSource::Jwt: + { + ProxyClass = UAsyncTaskThirdwebCreateJwtWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateJwtWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateJwtWallet, CreateJwtWallet); + break; + } + case EThirdwebInAppWalletSource::AuthEndpoint: + { + ProxyClass = UAsyncTaskThirdwebCreateAuthEndpointWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateAuthEndpointWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateAuthEndpointWallet, CreateAuthEndpointWallet); + break; + } + case EThirdwebInAppWalletSource::Guest: + { + ProxyClass = UAsyncTaskThirdwebCreateGuestWallet::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebCreateGuestWallet::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebCreateGuestWallet, CreateGuestWallet); + break; + } + } + } + RemovePin(GetTypePin()); + RemovePin(GetSourcePin()); + RemoveHiddenPins(this); + + Super::ExpandNode(CompilerContext, SourceGraph); +} + +void UK2Node_ThirdwebCreateWallet::UpdatePins() +{ + if (UEdGraphPin* Pin = GetTypePin()) + { + bool bSmart = ResolvePinValue(Pin) == TEXT("Smart"); + SetNodeHasAdvanced(UThirdwebRuntimeSettings::IsEcosystem() || bSmart); + FString Source = ResolvePinValue(GetSourcePin()); + SetPinVisibility(GetSourcePin(), !bSmart); + SetPinVisibility(GetProviderPin(), !bSmart && Source == TEXT("OAuth")); + SetPinFriendlyName( + SetPinVisibility(GetInputPin(), !bSmart && (Source == TEXT("Phone") || Source == TEXT("Email"))), + Source == TEXT("Phone") ? LOCTEXT("K2Node_ThirdwebCreateWallet_ThirdwebPhone", "Phone Number") : LOCTEXT("K2Node_ThirdwebCreateWallet_ThirdwebEmail", "Email Address") + ); + SetPinVisibility(GetWalletPin(), !bSmart); + SetPinVisibility(GetInAppWalletPin(), bSmart); + SetPinVisibility(GetChainIDPin(), bSmart); + SetPinVisibility(GetGaslessPin(), bSmart); + SetPinVisibility(GetFactoryPin(), bSmart); + SetPinVisibility(GetAccountOverridePin(), bSmart); + SetPinVisibility(GetSmartWalletPin(), bSmart); + + SetPinVisibility(GetPartnerIdPin(), UThirdwebRuntimeSettings::IsEcosystem()); + + if (UEdGraph* Graph = GetGraph()) + { + Graph->NotifyGraphChanged(); + } + } +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetTypePin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Type); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetSourcePin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Source); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + + + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetWalletPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Wallet); + check(Pin == NULL || Pin->Direction == EGPD_Output); + return Pin; +} + +// Smart Wallet Pins + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetChainIDPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::ChainID); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetGaslessPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Gasless); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetFactoryPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::Factory); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetAccountOverridePin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::AccountOverride); + check(Pin == NULL || Pin->Direction == EGPD_Input); + return Pin; +} + +UEdGraphPin* UK2Node_ThirdwebCreateWallet::GetSmartWalletPin() const +{ + UEdGraphPin* Pin = FindPin(TwPins::SmartWallet); + check(Pin == NULL || Pin->Direction == EGPD_Output); + return Pin; +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebLink.cpp b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebLink.cpp new file mode 100644 index 0000000..6728d3b --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebLink.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "K2Node/K2Node_ThirdwebLink.h" + +#include "AsyncTasks/Wallets/InApp/Link/AsyncTaskThirdwebLink.h" + +namespace LPins +{ + const FName Input = FName(TEXT("Input")); + const FName Wallet = FName(TEXT("Wallet")); + const FName NewWallet = FName(TEXT("NewWallet")); + const FName Success = FName(TEXT("Success")); + const FName Failed = FName(TEXT("Failed")); + const FName Error = FName(TEXT("Error")); +} + +#define LOCTEXT_NAMESPACE "ThirdwebUncookedOnly" + +UK2Node_ThirdwebLink::UK2Node_ThirdwebLink() +{ + ProxyClass = UAsyncTaskThirdwebLink::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebLink::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebLink, Link); +} + +FText UK2Node_ThirdwebLink::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + if (TitleType == ENodeTitleType::MenuTitle) + { + return LOCTEXT("K2Node_ThirdwebLink_SmartNodeTitle", "Link Wallet"); + } + return LOCTEXT("K2Node_ThirdwebLink_SmartNodeTitle", "Link Wallet"); +} + +FText UK2Node_ThirdwebLink::GetTooltipText() const +{ + return LOCTEXT("K2Node_ThirdwebLink_TooltipText", "Link a Thirdweb Wallet"); +} + +FText UK2Node_ThirdwebLink::GetMenuCategory() const +{ + return LOCTEXT("K2Node_ThirdwebLink_Category", "Thirdweb|Wallets|InApp"); +} + +void UK2Node_ThirdwebLink::PinDefaultValueChanged(UEdGraphPin* Pin) +{ + Super::Super::PinDefaultValueChanged(Pin); + UpdatePins(); +} + +void UK2Node_ThirdwebLink::AllocateDefaultPins() +{ + Super::AllocateDefaultPins(); + + // Input Pins + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Struct, FInAppWalletHandle::StaticStruct(), LPins::Wallet); + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Struct, FInAppWalletHandle::StaticStruct(), LPins::NewWallet); + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, LPins::Input); + + PostAllocateDefaultPins(); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignIn.cpp b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignIn.cpp new file mode 100644 index 0000000..8fc2001 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignIn.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "K2Node/K2Node_ThirdwebSignIn.h" + +#include "AsyncTasks/Wallets/InApp/SignIn/AsyncTaskThirdwebSignIn.h" + +#define LOCTEXT_NAMESPACE "ThirdwebUncookedOnly" + +UK2Node_ThirdwebSignIn::UK2Node_ThirdwebSignIn() +{ + ProxyClass = UAsyncTaskThirdwebSignIn::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebSignIn::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebSignIn, SignIn); +} + +FText UK2Node_ThirdwebSignIn::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + if (TitleType == ENodeTitleType::MenuTitle) + { + return LOCTEXT("K2Node_ThirdwebSignIn_SmartNodeTitle", "Sign In"); + } + return LOCTEXT("K2Node_ThirdwebSignIn_SmartNodeTitle", "Sign In"); +} + +FText UK2Node_ThirdwebSignIn::GetTooltipText() const +{ + return LOCTEXT("K2Node_ThirdwebSignIn_TooltipText", "Sign In With a Thirdweb Wallet"); +} + +FText UK2Node_ThirdwebSignIn::GetMenuCategory() const +{ + return LOCTEXT("K2Node_ThirdwebSignIn_Category", "Thirdweb|Wallets|InApp"); +} + +void UK2Node_ThirdwebSignIn::PinDefaultValueChanged(UEdGraphPin* Pin) +{ + Super::Super::PinDefaultValueChanged(Pin); + UpdatePins(); +} + +void UK2Node_ThirdwebSignIn::AllocateDefaultPins() +{ + Super::AllocateDefaultPins(); + + // Input Pins + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Struct, FInAppWalletHandle::StaticStruct(), TwPins::Wallet); + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::Input); + + PostAllocateDefaultPins(); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignMessage.cpp b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignMessage.cpp new file mode 100644 index 0000000..b69db72 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/K2Node/K2Node_ThirdwebSignMessage.cpp @@ -0,0 +1,119 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "K2Node/K2Node_ThirdwebSignMessage.h" + +#include "AsyncTasks/Wallets/InApp/AsyncTaskThirdwebInAppSignMessage.h" +#include "AsyncTasks/Wallets/Smart/AsyncTaskThirdwebSmartSignMessage.h" + +#include "Wallets/ThirdwebSmartWalletHandle.h" + +namespace TwPins +{ + const FName Message = FName(TEXT("Message")); + const FName SignedMessage = FName(TEXT("SignedMessage")); +} + +#define LOCTEXT_NAMESPACE "ThirdwebUncookedOnly" + +UK2Node_ThirdwebSignMessage::UK2Node_ThirdwebSignMessage() +{ + ProxyClass = UAsyncTaskThirdwebInAppSignMessage::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebInAppSignMessage::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebInAppSignMessage, SignMessage); +} + +FText UK2Node_ThirdwebSignMessage::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + return LOCTEXT("K2Node_ThirdwebSignMessage_SmartNodeTitle", "Sign Message"); +} + +FText UK2Node_ThirdwebSignMessage::GetTooltipText() const +{ + return LOCTEXT("K2Node_ThirdwebSignMessage_TooltipText", "Sign a Message with a Thirdweb Wallet"); +} + +FText UK2Node_ThirdwebSignMessage::GetMenuCategory() const +{ + return LOCTEXT("K2Node_ThirdwebSignMessage_Category", "Thirdweb|Wallets"); +} + +bool UK2Node_ThirdwebSignMessage::IsConnectionDisallowed(const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason) const +{ + if (MyPin == GetWalletPin() && OtherPin) + { + if (OtherPin->PinType.PinSubCategoryObject != TBaseStructure::Get() && OtherPin->PinType.PinSubCategoryObject != TBaseStructure::Get()) + { + OutReason = LOCTEXT("K2Node_ThirdwebSignMessage_IsConnectionDisallowed", "Only In App & Smart Wallet Handles allowed").ToString(); + return true; + } + } + return Super::IsConnectionDisallowed(MyPin, OtherPin, OutReason); +} + +void UK2Node_ThirdwebSignMessage::PinDefaultValueChanged(UEdGraphPin* Pin) +{ + Super::Super::PinDefaultValueChanged(Pin); + UpdatePins(); +} + +void UK2Node_ThirdwebSignMessage::AllocateDefaultPins() +{ + Super::AllocateDefaultPins(); + + // Input Pins + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, TwPins::Wallet); + + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, TwPins::Message); + + // Output Pins + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_String, TwPins::SignedMessage); + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_String, TwPins::Error); + + UpdatePins(); +} + +void UK2Node_ThirdwebSignMessage::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) +{ + if (UEdGraphPin* Pin = GetWalletPin()) + { + if (Pin->PinType.PinSubCategoryObject == TBaseStructure::Get()) + { + ProxyClass = UAsyncTaskThirdwebSmartSignMessage::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebSmartSignMessage::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebSmartSignMessage, SignMessage); + } + else + { + ProxyClass = UAsyncTaskThirdwebInAppSignMessage::StaticClass(); + ProxyFactoryClass = UAsyncTaskThirdwebInAppSignMessage::StaticClass(); + ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAsyncTaskThirdwebInAppSignMessage, SignMessage); + } + } + Super::ExpandNode(CompilerContext, SourceGraph); +} + +void UK2Node_ThirdwebSignMessage::UpdatePins() +{ + if (UEdGraphPin* Pin = GetWalletPin()) + { + if (UEdGraphPin* ConnectedPin = GetConnectedPin(Pin)) + { + if (Pin->PinType != ConnectedPin->PinType) + { + Pin->PinType = ConnectedPin->PinType; + GetGraph()->NotifyGraphChanged(); + } + } + else + { + if (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Wildcard) + { + Pin->PinType.PinCategory = UEdGraphSchema_K2::PC_Wildcard; + Pin->BreakAllPinLinks(); + GetGraph()->NotifyGraphChanged(); + } + } + } +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/ThirdwebUncookedOnly/Private/ThirdwebUncookedOnly.cpp b/Source/ThirdwebUncookedOnly/Private/ThirdwebUncookedOnly.cpp new file mode 100644 index 0000000..fecd84e --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Private/ThirdwebUncookedOnly.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#include "ThirdwebUncookedOnly.h" + +#define LOCTEXT_NAMESPACE "FThirdwebUncookedOnlyModule" + +void FThirdwebUncookedOnlyModule::StartupModule() +{ + +} + +void FThirdwebUncookedOnlyModule::ShutdownModule() +{ + +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FThirdwebUncookedOnlyModule, ThirdwebUncookedOnly) \ No newline at end of file diff --git a/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebBaseAsyncTask.h b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebBaseAsyncTask.h new file mode 100644 index 0000000..8f3f36f --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebBaseAsyncTask.h @@ -0,0 +1,88 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "K2Node_BaseAsyncTask.h" +#include "K2Node_ThirdwebBaseAsyncTask.generated.h" + +namespace TwPins +{ + extern const FName Provider; + extern const FName Input; + extern const FName PartnerId; + extern const FName Wallet; + extern const FName InAppWallet; + extern const FName SmartWallet; + extern const FName Success; + extern const FName Failed; + extern const FName Error; +} + +UCLASS(Abstract) +class THIRDWEBUNCOOKEDONLY_API UK2Node_ThirdwebBaseAsyncTask : public UK2Node_BaseAsyncTask +{ + GENERATED_BODY() + +protected: + FNodeTextCache CachedNodeTitle; + +public: + UK2Node_ThirdwebBaseAsyncTask(); + + // UEdGraphNode interface implementation + virtual FLinearColor GetNodeTitleColor() const override; + virtual FSlateIcon GetIconAndTint(FLinearColor& OutColor) const override; + virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; + // End of implementation + + + // UK2Node interface implementation + virtual FText GetMenuCategory() const override; + virtual void PostReconstructNode() override; + virtual void NotifyPinConnectionListChanged(UEdGraphPin* Pin) override; + // End of implementation + + virtual void AllocateDefaultPins() override; + virtual void PostAllocateDefaultPins(); +protected: + /** Set the value of `bHidden` on the pin */ + static UEdGraphPin* SetPinVisibility(UEdGraphPin* Pin, const bool bShow); + + /** Set the value of `PinFriendlyName` on the pin */ + static UEdGraphPin* SetPinFriendlyName(UEdGraphPin* Pin, const FText& FriendlyName); + + /** Set the value of `bNotConnectable` to true on the pin */ + static UEdGraphPin* SetPinConnectable(UEdGraphPin* Pin, const bool bConnectable = false); + + /** Set the value of `bAdvancedView` on the pin */ + static UEdGraphPin* SetPinAdvancedView(UEdGraphPin* Pin, const bool bAdvanced = true); + + /** Destroy all hidden pins */ + static void RemoveHiddenPins(UK2Node* K2Node); + + /** Get the pin connected to the current pin */ + static UEdGraphPin* GetConnectedPin(UEdGraphPin* Pin); + + /** Get the resolved value of the pin */ + static FString ResolvePinValue(UEdGraphPin* Pin); + + /** Set the value of `AutogeneratedDefaultValue` on the pin */ + static UEdGraphPin* SetPinDefaultValue(UEdGraphPin* Pin, const FString& Value); + + /** Update All pins based on logic */ + virtual void UpdatePins() {} + /** Set the value of `AdvancedPinDisplay` on the node */ + void SetNodeHasAdvanced(const bool bHasAdvanced); + + + /** Pin Getters */ + virtual UEdGraphPin* GetProviderPin() const; + virtual UEdGraphPin* GetInputPin() const; + virtual UEdGraphPin* GetPartnerIdPin() const; + virtual UEdGraphPin* GetWalletPin() const; + virtual UEdGraphPin* GetInAppWalletPin() const; + virtual UEdGraphPin* GetSmartWalletPin() const; + virtual UEdGraphPin* GetSuccessPin() const; + virtual UEdGraphPin* GetFailedPin() const; + virtual UEdGraphPin* GetErrorPin() const; +}; diff --git a/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebCreateWallet.h b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebCreateWallet.h new file mode 100644 index 0000000..f487b51 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebCreateWallet.h @@ -0,0 +1,52 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "K2Node.h" +#include "K2Node_ThirdwebBaseAsyncTask.h" +#include "K2Node_ThirdwebCreateWallet.generated.h" + +namespace TwPins +{ + extern const FName Type; + extern const FName Source; + extern const FName Provider; + // Smart Wallet Pins + extern const FName ChainID; + extern const FName Gasless; + extern const FName Factory; + extern const FName AccountOverride; +} + +UCLASS() +class THIRDWEBUNCOOKEDONLY_API UK2Node_ThirdwebCreateWallet : public UK2Node_ThirdwebBaseAsyncTask +{ + GENERATED_BODY() + +public: + UK2Node_ThirdwebCreateWallet(); + + // UEdGraphNode interface implementation + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FText GetTooltipText() const override; + virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; + // End of implementation + + virtual void AllocateDefaultPins() override; + virtual void ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override; + +protected: + virtual void UpdatePins() override; + + // Base Pins + UEdGraphPin* GetTypePin() const; + UEdGraphPin* GetSourcePin() const; + virtual UEdGraphPin* GetWalletPin() const override; + + // Smart Wallet Pins + UEdGraphPin* GetChainIDPin() const; + UEdGraphPin* GetGaslessPin() const; + UEdGraphPin* GetFactoryPin() const; + UEdGraphPin* GetAccountOverridePin() const; + virtual UEdGraphPin* GetSmartWalletPin() const override; +}; diff --git a/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebLink.h b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebLink.h new file mode 100644 index 0000000..dbe61e2 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebLink.h @@ -0,0 +1,39 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "K2Node.h" +#include "K2Node_ThirdwebBaseAsyncTask.h" +#include "K2Node_ThirdwebLink.generated.h" + +namespace LPins +{ + extern const FName Input; + extern const FName Wallet; + extern const FName NewWallet; + extern const FName Success; + extern const FName Failed; + extern const FName Error; + +} + +UCLASS() +class THIRDWEBUNCOOKEDONLY_API UK2Node_ThirdwebLink : public UK2Node_ThirdwebBaseAsyncTask +{ + GENERATED_BODY() + +public: + UK2Node_ThirdwebLink(); + + // UEdGraphNode interface implementation + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FText GetTooltipText() const override; + virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; + // End of implementation + + // UK2Node interface implementation + virtual FText GetMenuCategory() const override; + // End of implementation + + virtual void AllocateDefaultPins() override; +}; diff --git a/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignIn.h b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignIn.h new file mode 100644 index 0000000..20ad664 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignIn.h @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "K2Node.h" +#include "K2Node_ThirdwebBaseAsyncTask.h" +#include "K2Node_ThirdwebSignIn.generated.h" + +UCLASS() +class THIRDWEBUNCOOKEDONLY_API UK2Node_ThirdwebSignIn : public UK2Node_ThirdwebBaseAsyncTask +{ + GENERATED_BODY() + +public: + UK2Node_ThirdwebSignIn(); + + // UEdGraphNode interface implementation + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FText GetTooltipText() const override; + virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; + // End of implementation + + // UK2Node interface implementation + virtual FText GetMenuCategory() const override; + // End of implementation + + virtual void AllocateDefaultPins() override; +}; diff --git a/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignMessage.h b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignMessage.h new file mode 100644 index 0000000..de30908 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/K2Node/K2Node_ThirdwebSignMessage.h @@ -0,0 +1,39 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "K2Node.h" +#include "K2Node_ThirdwebBaseAsyncTask.h" +#include "K2Node_ThirdwebSignMessage.generated.h" + +namespace TwPins +{ + extern const FName Message; + extern const FName SignedMessage; +} + +UCLASS() +class THIRDWEBUNCOOKEDONLY_API UK2Node_ThirdwebSignMessage : public UK2Node_ThirdwebBaseAsyncTask +{ + GENERATED_BODY() + +public: + UK2Node_ThirdwebSignMessage(); + + // UEdGraphNode interface implementation + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FText GetTooltipText() const override; + virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; + // End of implementation + + // UK2Node interface implementation + virtual FText GetMenuCategory() const override; + virtual bool IsConnectionDisallowed(const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason) const override; + // End of implementation + + virtual void AllocateDefaultPins() override; + virtual void ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override; + +protected: + virtual void UpdatePins() override; +}; diff --git a/Source/ThirdwebUncookedOnly/Public/TWUOCommon.h b/Source/ThirdwebUncookedOnly/Public/TWUOCommon.h new file mode 100644 index 0000000..0aa698d --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/TWUOCommon.h @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "HAL/Platform.h" + +#include "Internationalization/Internationalization.h" + +#include "TWUOCommon.generated.h" + + +UENUM(BlueprintType, DisplayName="Thirdweb Wallet Type") +enum class EThirdwebWalletType : uint8 +{ + InApp UMETA(DisplayName="In App"), + Smart UMETA(DisplayName="Smart") +}; + +UENUM(BlueprintType, DisplayName="Thirdweb In App Wallet Source") +enum class EThirdwebInAppWalletSource : uint8 +{ + OAuth UMETA(DisplayName="OAuth"), + Email UMETA(DisplayName="Email"), + Phone UMETA(DisplayName="Phone"), + Jwt UMETA(DisplayName="JWT"), + AuthEndpoint UMETA(DisplayName="Auth Endpoint"), + Guest UMETA(DisplayName="Guest"), +}; \ No newline at end of file diff --git a/Source/ThirdwebUncookedOnly/Public/TWUOUtils.h b/Source/ThirdwebUncookedOnly/Public/TWUOUtils.h new file mode 100644 index 0000000..e008776 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/TWUOUtils.h @@ -0,0 +1,31 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once +#include "TWUOCommon.h" + +namespace ThirdwebUtils +{ + namespace Maps + { + static const TMap InAppWalletSourceToString = { + {EThirdwebInAppWalletSource::OAuth, TEXT("OAuth")}, + {EThirdwebInAppWalletSource::Email, TEXT("Email")}, + {EThirdwebInAppWalletSource::Phone, TEXT("Phone")}, + {EThirdwebInAppWalletSource::Jwt, TEXT("Jwt")}, + {EThirdwebInAppWalletSource::AuthEndpoint, TEXT("AuthEndpoint")}, + {EThirdwebInAppWalletSource::Guest, TEXT("Guest")}, + }; + } + + static EThirdwebInAppWalletSource ToInAppWalletSource(const FString& Source) + { + for (const auto& It : Maps::InAppWalletSourceToString) + { + if (It.Value.Equals(Source, ESearchCase::IgnoreCase)) + { + return It.Key; + } + } + return EThirdwebInAppWalletSource::OAuth; + } +} diff --git a/Source/ThirdwebUncookedOnly/Public/ThirdwebUncookedOnly.h b/Source/ThirdwebUncookedOnly/Public/ThirdwebUncookedOnly.h new file mode 100644 index 0000000..5c2d842 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/Public/ThirdwebUncookedOnly.h @@ -0,0 +1,12 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +#pragma once + +#include "Modules/ModuleManager.h" + +class FThirdwebUncookedOnlyModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; diff --git a/Source/ThirdwebUncookedOnly/ThirdwebUncookedOnly.Build.cs b/Source/ThirdwebUncookedOnly/ThirdwebUncookedOnly.Build.cs new file mode 100644 index 0000000..e620a76 --- /dev/null +++ b/Source/ThirdwebUncookedOnly/ThirdwebUncookedOnly.Build.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2024 Thirdweb. All Rights Reserved. + +using UnrealBuildTool; + +public class ThirdwebUncookedOnly : ModuleRules +{ + public ThirdwebUncookedOnly(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; +#if UE_5_3_OR_LATER + IncludeOrderVersion = EngineIncludeOrderVersion.Latest; +#endif + PublicDependencyModuleNames.AddRange(new[] + { + "Core", + "Thirdweb", + "DeveloperSettings", + "KismetCompiler", + "BlueprintGraph", + "UnrealEd" + }); + + PrivateDependencyModuleNames.AddRange(new[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore" + }); + } +} \ No newline at end of file diff --git a/Thirdweb.uplugin b/Thirdweb.uplugin index e6bf35e..e676b7d 100644 --- a/Thirdweb.uplugin +++ b/Thirdweb.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, - "Version": 140, - "VersionName": "1.4.0", + "Version": 150, + "VersionName": "1.5.0", "FriendlyName": "Thirdweb", "Description": "Unreal Integration of Thirdweb Wallets", "Category": "Thirdweb", @@ -35,6 +35,11 @@ "Name": "ThirdwebEditor", "Type": "Editor", "LoadingPhase": "Default" + }, + { + "Name": "ThirdwebUncookedOnly", + "Type": "UncookedOnly", + "LoadingPhase": "Default" } ] -} +} \ No newline at end of file