Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3b6dd66

Browse files
YermekGImmutableJeffrey
andauthoredJan 20, 2025
feat: added transak widget (#158)
* feat: added transak config * feat: added transak web widget and environment enum * feat: added missing module * fix: resolved compile issue with ue4 * fix: compiler issue with ue4 * chore: isolated source code for ue5 * chore: removed requirement of folder name in branch name (#157) * feat: add 4.26 support to transak widget (#156) * feat: added transak web widget and environment enum * fix: resolved compile issue with ue4 * fix: compiler issue with ue4 * chore: isolated source code for ue5 * feat: add blu web browser to transak widget (#3498) * refactor: apply formatting * refactor: move include inside respective engine macro * refactor: expose is ready to blueprint * refactor: change private to protected * refactor: reorder .h and .cpp functions to match each other * chore: update loctext namespace * fix: compile error * chore: removed redundant code * chore: removed prefixes --------- Co-authored-by: Yermek Garifullanov <yermek.garifullanov@immutable.com> * chore: added comments and moved to dedicated folder * feat: added sample asset for transak widget * fix: minor changes for consts and enums * fix: resolved compile issues with ue 5.4 * refactor: added marketplace module and renamed transak widget * refactor: added marketplace module to keep marketplace features such as on ramp widget * chore: renamed transak widget to on ramp * chore: change misleading transak wording * chore: source code polish * chore: add custom openapi template (#3423) * fix: openapi generator unique items conflicting with array (#3423) * chore: update openapi.json (#3423) * refactor: to generate openapi with batch files (#3423) * chore: manually update openapi files (#3423) * feat: implement oneof for data models (#3518) * feat: automate the process of updating zkevm repo when it's corresponding openapi changes (#3497) * fix: linting errors for zkevm api scripts (#3522) --------- Co-authored-by: ImmutableJeffrey <jeffrey.wong@immutable.com>
1 parent 7cebc7e commit 3b6dd66

21 files changed

+721
-87
lines changed
 

‎.github/workflows/branch-name.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ jobs:
99
- uses: deepakputhraya/action-branch-name@master
1010
with:
1111
regex: '([a-z])*\/?([a-z0-9.-])+'
12-
allowed_prefixes: 'feat,fix,build,chore,ci,docs,style,refactor,perf,test,revert,release'
1312
ignore: main
1413
min_length: 5
1514
max_length: 50
Binary file not shown.
Binary file not shown.

‎Immutable.uplugin

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,60 @@
1-
{
2-
"FileVersion": 3,
3-
"Version": 1,
4-
"VersionName": "1.3.0.alpha",
5-
"FriendlyName": "Immutable",
6-
"Description": "",
7-
"Category": "Other",
8-
"CreatedBy": "",
9-
"CreatedByURL": "",
10-
"DocsURL": "",
11-
"MarketplaceURL": "",
12-
"SupportURL": "",
13-
"EnabledByDefault": true,
14-
"CanContainContent": true,
15-
"IsBetaVersion": true,
16-
"IsExperimentalVersion": true,
17-
"Installed": true,
18-
"Modules": [
19-
{
20-
"Name": "Immutable",
21-
"Type": "Runtime",
22-
"LoadingPhase": "Default"
23-
},
24-
{
25-
"Name": "ImmutableEditor",
26-
"Type": "Editor",
27-
"LoadingPhase": "Default"
28-
},
29-
{
30-
"Name": "ImmutablePluginManager",
31-
"Type": "Runtime",
32-
"LoadingPhase": "EarliestPossible"
33-
},
34-
{
35-
"Name": "ImmutableOrderbook",
36-
"Type": "Runtime",
37-
"LoadingPhase": "Default"
38-
},
39-
{
40-
"Name": "ImmutablezkEVMAPI",
41-
"Type": "Runtime",
42-
"LoadingPhase": "Default"
43-
}
44-
]
1+
{
2+
"FileVersion": 3,
3+
"Version": 1,
4+
"VersionName": "1.3.0.alpha",
5+
"FriendlyName": "Immutable",
6+
"Description": "",
7+
"Category": "Other",
8+
"CreatedBy": "",
9+
"CreatedByURL": "",
10+
"DocsURL": "",
11+
"MarketplaceURL": "",
12+
"SupportURL": "",
13+
"EnabledByDefault": true,
14+
"CanContainContent": true,
15+
"IsBetaVersion": true,
16+
"IsExperimentalVersion": true,
17+
"Installed": true,
18+
"Modules": [
19+
{
20+
"Name": "Immutable",
21+
"Type": "Runtime",
22+
"LoadingPhase": "Default"
23+
},
24+
{
25+
"Name": "ImmutableEditor",
26+
"Type": "Editor",
27+
"LoadingPhase": "Default"
28+
},
29+
{
30+
"Name": "ImmutablePluginManager",
31+
"Type": "Runtime",
32+
"LoadingPhase": "EarliestPossible"
33+
},
34+
{
35+
"Name": "ImmutableOrderbook",
36+
"Type": "Runtime",
37+
"LoadingPhase": "Default"
38+
},
39+
{
40+
"Name": "ImmutablezkEVMAPI",
41+
"Type": "Runtime",
42+
"LoadingPhase": "Default"
43+
},
44+
{
45+
"Name": "ImmutableMarketplace",
46+
"Type": "Runtime",
47+
"LoadingPhase": "Default"
48+
}
49+
],
50+
"Plugins": [
51+
{
52+
"Name": "BLUI",
53+
"Enabled": true
54+
},
55+
{
56+
"Name": "WebBrowserWidget",
57+
"Enabled": false
58+
}
59+
]
4560
}

‎Source/Immutable/Immutable.Build.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public Immutable(ReadOnlyTargetRules Target) : base(Target)
1919
new string[]
2020
{
2121
"Core",
22-
"JsonUtilities",
22+
"JsonUtilities",
2323
}
2424
);
2525

@@ -34,19 +34,27 @@ public Immutable(ReadOnlyTargetRules Target) : base(Target)
3434
"UMG",
3535
"Projects",
3636
"DeveloperSettings",
37+
"HTTP",
3738
}
3839
);
3940

40-
#if UE_5_0_OR_LATER
41-
PublicDependencyModuleNames.Add("WebBrowserWidget");
41+
#if UE_5_1_OR_LATER
42+
PublicDependencyModuleNames.AddRange(
43+
new string[]
44+
{
45+
"WebBrowser",
46+
"WebBrowserWidget"
47+
}
48+
);
4249
#else
50+
PrivateDependencyModuleNames.Add("BluExtension");
4351
if (Target.Platform == UnrealTargetPlatform.Win64)
4452
{
4553
PublicDependencyModuleNames.Add("Blu");
4654
}
4755
#endif
4856

49-
#if UE_5_0_OR_LATER
57+
#if UE_5_1_OR_LATER
5058
PrivateDependencyModuleNames.Add("WebBrowser");
5159
PublicDefinitions.Add("USING_BUNDLED_CEF=1");
5260
PublicDefinitions.Add("USING_BLUI_CEF=0");

‎Source/Immutable/Private/Immutable/ImmutablePassport.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
#include "ImmutableAnalytics.h"
66
#include "Immutable/Misc/ImtblLogging.h"
7-
#include "Immutable/ImmutableResponses.h"
87
#include "Immutable/ImtblJSConnector.h"
98
#include "JsonObjectConverter.h"
109
#include "Immutable/ImmutableSaveGame.h"
11-
#include "Immutable/ImmutableUtilities.h"
10+
#include "Immutable/ImmutableSettings.h"
1211
#include "Kismet/GameplayStatics.h"
13-
#include "Policies/CondensedJsonPrintPolicy.h"
1412

1513
#if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC
1614
#include "GenericPlatform/GenericPlatformHttp.h"
@@ -49,8 +47,17 @@ void UImmutablePassport::Initialize(const FImmutablePassportInitData& Data, cons
4947
void UImmutablePassport::Initialize(const FImtblPassportResponseDelegate& ResponseDelegate)
5048
{
5149
check(JSConnector.IsValid());
50+
51+
auto Settings = GetDefault<UImmutableSettings>();
52+
53+
if (Settings)
54+
{
55+
ResponseDelegate.ExecuteIfBound(FImmutablePassportResult{false, "Failed to find Immutable Settings"});
56+
57+
return;
58+
}
5259

53-
UApplicationConfig* ApplicationConfig = FImmutableUtilities::GetDefaultApplicationConfig();
60+
UApplicationConfig* ApplicationConfig = Settings->DefaultApplicationConfig.GetDefaultObject();
5461

5562
if (!ApplicationConfig)
5663
{
@@ -60,7 +67,7 @@ void UImmutablePassport::Initialize(const FImtblPassportResponseDelegate& Respon
6067
}
6168

6269
InitData.clientId = ApplicationConfig->GetClientID();
63-
InitData.environment = ApplicationConfig->GetEnvironment();
70+
InitData.environment = ApplicationConfig->GetEnvironmentString();
6471
InitData.redirectUri = ApplicationConfig->GetRedirectURL();
6572
InitData.logoutRedirectUri = ApplicationConfig->GetLogoutURL();
6673

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "Immutable/ImmutableUtilities.h"
22

3-
#include "Immutable/ImmutablePluginSettings.h"
43
#include "Immutable/Misc/ImtblLogging.h"
54
#include "Interfaces/IPluginManager.h"
65
#include "Misc/FileHelper.h"
@@ -20,15 +19,3 @@ bool FImmutableUtilities::LoadGameBridge(FString& GameBridge)
2019

2120
return false;
2221
}
23-
24-
UApplicationConfig* FImmutableUtilities::GetDefaultApplicationConfig()
25-
{
26-
auto Settings = GetDefault<UImmutablePluginSettings>();
27-
28-
if (!Settings)
29-
{
30-
return nullptr;
31-
}
32-
33-
return Settings->DefaultApplicationConfig.GetDefaultObject();
34-
}

‎Source/Immutable/Private/Immutable/Tests/ImtblMessagesTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bool FImtblMessagesTest::RunTest(const FString& Parameters)
4040
// string
4141
{
4242
const FString RedirectUri = "https://example.com";
43-
const FImmutablePassportInitData InitData{ClientId, RedirectUri, ImmutablePassportAction::EnvSandbox};
43+
const FImmutablePassportInitData InitData { ClientId, RedirectUri, ImmutablePassportEnvironmentConstants::EnvironmentSandbox };
4444
FString ExpectedJson = "{\"clientId\":\"MyExampleClientId\",\"redirectUri\":\"https://" "example.com\",\"environment\":\"sandbox\"";
4545
ExpectedJson += ",\"engineVersion\":{";
4646
ExpectedJson += "\"engine\":\"unreal\"";
@@ -57,7 +57,7 @@ bool FImtblMessagesTest::RunTest(const FString& Parameters)
5757
// an FImmutablePassportInitData with an empty redirectUri should leave the
5858
// redirectUri field out of the json string when converted
5959
{
60-
const FImmutablePassportInitData InitData{ClientId, "", ImmutablePassportAction::EnvSandbox};
60+
const FImmutablePassportInitData InitData { ClientId, "", ImmutablePassportEnvironmentConstants::EnvironmentSandbox };
6161
FString ExpectedJson = "{\"clientId\":\"MyExampleClientId\",\"environment\":\"sandbox\"";
6262
ExpectedJson += ",\"engineVersion\":{";
6363
ExpectedJson += "\"engine\":\"unreal\"";

‎Source/Immutable/Public/Immutable/ApplicationConfig.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#pragma once
22

3+
#include "ImmutableEnums.h"
4+
#include "ImmutableNames.h"
5+
36
#include "ApplicationConfig.generated.h"
47

58
/**
@@ -9,7 +12,7 @@
912
* client IDs, and environment settings for the zkEVM API, Orderbook API, and Passport.
1013
*/
1114
UCLASS(Abstract, Blueprintable, ClassGroup = Immutable)
12-
class UApplicationConfig : public UObject
15+
class IMMUTABLE_API UApplicationConfig : public UObject
1316
{
1417
GENERATED_BODY()
1518

@@ -85,13 +88,20 @@ class UApplicationConfig : public UObject
8588
}
8689

8790
/**
88-
* Retrieves the environment configuration used for Passport initialization.
91+
* Retrieves the environment configuration used for Passport initialization as FString .
8992
*
9093
* @return A constant reference to an FString representing the environment.
9194
*/
92-
const FString& GetEnvironment()
95+
const FString& GetEnvironmentString() const
9396
{
94-
return Environment;
97+
switch (Environment)
98+
{
99+
case EPassportEnvironment::Production:
100+
return ImmutablePassportEnvironmentConstants::EnvironmentProduction;
101+
default:
102+
case EPassportEnvironment::Sandbox:
103+
return ImmutablePassportEnvironmentConstants::EnvironmentProduction;
104+
}
95105
}
96106

97107
/**
@@ -144,9 +154,12 @@ class UApplicationConfig : public UObject
144154
UPROPERTY(EditDefaultsOnly, Category = "Passport")
145155
FString ClientID;
146156

147-
/** Environment used to initialize passport. Ex. sandbox or production */
157+
/**
158+
* Environment used to initialize passport. Ex. sandbox or production.
159+
* @note The default environment is set to the Sandbox environment.
160+
*/
148161
UPROPERTY(EditDefaultsOnly, Category = "Passport")
149-
FString Environment;
162+
EPassportEnvironment Environment = EPassportEnvironment::Sandbox;
150163

151164
/**
152165
* (Android, iOS, and macOS only)

‎Source/Immutable/Public/Immutable/ImmutableDataTypes.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ struct IMMUTABLE_API FImmutablePassportInitData
6161
UPROPERTY()
6262
FString logoutRedirectUri;
6363

64-
/** The environment to connect to. */
64+
/** The environment to connect to.
65+
* @note Default value is "sandbox"
66+
*/
6567
UPROPERTY()
66-
FString environment = ImmutablePassportAction::EnvSandbox;
68+
FString environment = ImmutablePassportEnvironmentConstants::EnvironmentSandbox;
6769

6870
/**
6971
* Whether silent logout is enabled.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
UENUM(BlueprintType)
4+
enum class EPassportEnvironment : uint8
5+
{
6+
Development,
7+
Sandbox,
8+
Production,
9+
};
10+

‎Source/Immutable/Public/Immutable/ImmutableNames.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace ImmutablePassportAction
2020

2121
#if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC
2222
const FString GetPKCEAuthUrl = TEXT("getPKCEAuthUrl");
23-
const FString LOGIN_PKCE = TEXT("loginPKCE");; //+
23+
const FString LOGIN_PKCE = TEXT("loginPKCE");
2424
const FString CONNECT_PKCE = TEXT("connectPKCE");
2525
#endif
2626

@@ -31,10 +31,14 @@ namespace ImmutablePassportAction
3131
const FString GetLinkedAddresses = TEXT("getLinkedAddresses");
3232
const FString ImxTransfer = TEXT("imxTransfer");
3333
const FString ImxBatchNftTransfer = TEXT("imxBatchNftTransfer");
34-
const FString EnvSandbox = TEXT("sandbox");
35-
const FString EnvProduction = TEXT("production");
3634
const FString ImxIsRegisteredOffchain = TEXT("isRegisteredOffchain");
3735
const FString ImxRegisterOffchain = TEXT("registerOffchain");
3836

3937
const FString TRACK = TEXT("track");
4038
} // namespace ImmutablePassportAction
39+
40+
namespace ImmutablePassportEnvironmentConstants
41+
{
42+
const FString EnvironmentSandbox = TEXT("sandbox");
43+
const FString EnvironmentProduction = TEXT("production");
44+
}

‎Source/Immutable/Public/Immutable/ImmutablePluginSettings.h renamed to ‎Source/Immutable/Public/Immutable/ImmutableSettings.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
#include "Engine/DeveloperSettings.h"
44
#include "ApplicationConfig.h"
55

6-
#include "ImmutablePluginSettings.generated.h"
6+
#include "ImmutableSettings.generated.h"
77

88

99
/**
10-
* ImmutablePluginSettings is a configuration class for the Immutable plugin.
10+
* Immutable developer settings is a configuration class for the Immutable plugin.
1111
* This class contains settings that can be adjusted to control the behavior
1212
* of the Immutable plugin within the Unreal Engine environment.
1313
*/
14-
UCLASS(config = Game, defaultconfig, meta = (DisplayName = "Immutable Plugin Settings"))
15-
class IMMUTABLE_API UImmutablePluginSettings : public UDeveloperSettings
14+
UCLASS(config = Game, defaultconfig, meta = (DisplayName = "Immutable"))
15+
class IMMUTABLE_API UImmutableSettings : public UDeveloperSettings
1616
{
1717
GENERATED_BODY()
1818

@@ -22,4 +22,5 @@ class IMMUTABLE_API UImmutablePluginSettings : public UDeveloperSettings
2222
/// which will be used as the default configuration for the application.
2323
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "General")
2424
TSubclassOf<UApplicationConfig> DefaultApplicationConfig;
25+
2526
};

‎Source/Immutable/Public/Immutable/ImmutableUtilities.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#pragma once
2-
#include "ApplicationConfig.h"
32

43

54
/** A wrapper struct around various Immutable namespace utility and support methods. */
@@ -13,6 +12,4 @@ struct IMMUTABLE_API FImmutableUtilities
1312
* @return True if the game bridge content was sucessfully retrieved. Otherwise, false.
1413
*/
1514
static bool LoadGameBridge(FString& GameBridge);
16-
17-
static UApplicationConfig* GetDefaultApplicationConfig();
1815
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using UnrealBuildTool;
2+
3+
public class ImmutableMarketplace : ModuleRules
4+
{
5+
public ImmutableMarketplace(ReadOnlyTargetRules Target) : base(Target)
6+
{
7+
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
8+
9+
PublicDependencyModuleNames.AddRange(
10+
new string[]
11+
{
12+
"Core",
13+
"UMG"
14+
}
15+
);
16+
17+
PrivateDependencyModuleNames.AddRange(
18+
new string[]
19+
{
20+
"CoreUObject",
21+
"Engine",
22+
"Slate",
23+
"SlateCore",
24+
"DeveloperSettings",
25+
"HTTP"
26+
}
27+
);
28+
29+
#if UE_5_1_OR_LATER
30+
PublicDependencyModuleNames.AddRange(
31+
new string[]
32+
{
33+
"WebBrowser",
34+
}
35+
);
36+
#else
37+
PrivateDependencyModuleNames.Add("BluExtension");
38+
if (Target.Platform == UnrealTargetPlatform.Win64)
39+
{
40+
PublicDependencyModuleNames.Add("Blu");
41+
}
42+
#endif
43+
}
44+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "ImmutableMarketplace.h"
2+
3+
#define LOCTEXT_NAMESPACE "FImmutableMarketplaceModule"
4+
5+
void FImmutableMarketplaceModule::StartupModule()
6+
{
7+
8+
}
9+
10+
void FImmutableMarketplaceModule::ShutdownModule()
11+
{
12+
13+
}
14+
15+
#undef LOCTEXT_NAMESPACE
16+
17+
IMPLEMENT_MODULE(FImmutableMarketplaceModule, ImmutableMarketplace)
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#include "OnRampWebBrowserWidget.h"
2+
3+
#include "ImmutableMarketplaceSettings.h"
4+
#include "PlatformHttp.h"
5+
6+
#include "OnRampWidgetConfig.h"
7+
8+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
9+
#include "SWebBrowser.h"
10+
#else
11+
#include "UserInterface/BluWebBrowser.h"
12+
#endif
13+
14+
#define LOCTEXT_NAMESPACE "OnRampWidget"
15+
16+
DEFINE_LOG_CATEGORY(LogImmutableOnRampWidget);
17+
18+
19+
bool UOnRampWidget::IsReady() const
20+
{
21+
return bIsReady;
22+
}
23+
24+
void UOnRampWidget::Load(const FString& WalletAddress, const FString& Email, const FString& ProductsAvailed, const FString& ScreenTitle)
25+
{
26+
if (!WebBrowserWidget.IsValid())
27+
{
28+
return;
29+
}
30+
31+
FString UrlToLoad = ComputePath(WalletAddress, Email, ProductsAvailed, ScreenTitle);
32+
CallAndRegister_OnWhenReady(UOnRampWidget::FOnWhenReady::FDelegate::CreateWeakLambda(this, [this, UrlToLoad]()
33+
{
34+
WebBrowserWidget->LoadURL(UrlToLoad);
35+
OnWhenReady.RemoveAll(this);
36+
}));
37+
}
38+
39+
FDelegateHandle UOnRampWidget::CallAndRegister_OnWhenReady(FOnWhenReady::FDelegate Delegate)
40+
{
41+
if (bIsReady)
42+
{
43+
Delegate.ExecuteIfBound();
44+
}
45+
46+
return OnWhenReady.Add(Delegate);
47+
}
48+
49+
TSharedRef<SWidget> UOnRampWidget::RebuildWidget()
50+
{
51+
if (IsDesignTime())
52+
{
53+
return SNew(SBox)
54+
.HAlign(HAlign_Center)
55+
.VAlign(VAlign_Center)
56+
[
57+
SNew(STextBlock)
58+
.Text(LOCTEXT("OnRamp Web Browser", "OnRamp Web Browser"))
59+
];
60+
}
61+
else
62+
{
63+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
64+
WebBrowserWidget = SNew(SWebBrowser)
65+
.InitialURL(InitialURL)
66+
.ShowControls(false)
67+
.SupportsTransparency(false)
68+
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged))
69+
.OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup))
70+
.OnConsoleMessage(BIND_UOBJECT_DELEGATE(FOnConsoleMessageDelegate, HandleOnConsoleMessage));
71+
return WebBrowserWidget.ToSharedRef();
72+
#else
73+
WebBrowserWidget = SNew(SBluWebBrowser)
74+
.InitialURL(InitialURL)
75+
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged));
76+
return WebBrowserWidget.ToSharedRef();
77+
#endif
78+
}
79+
}
80+
81+
FString UOnRampWidget::ComputePath(const FString& WalletAddress, const FString& Email, const FString& ProductsAvailed, const FString& ScreenTitle)
82+
{
83+
auto Settings = GetDefault<UImmutableMarketplaceSettings>();
84+
85+
UOnRampWidgetConfig* OnRampWidgetConfig = Settings->DefaultOnRampWidgetConfig.GetDefaultObject();
86+
87+
if (!OnRampWidgetConfig)
88+
{
89+
UE_LOG(LogImmutableOnRampWidget, Error, TEXT("On ramp widget config is not assigned!"));
90+
91+
return TEXT("");
92+
}
93+
94+
FString Path = OnRampWidgetConfig->GetURL();
95+
TArray<FString> QueryParams;
96+
97+
QueryParams.Add(FString(TEXT("apiKey=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetAPIKey()));
98+
QueryParams.Add(FString(TEXT("email=")) + FPlatformHttp::UrlEncode(Email));
99+
QueryParams.Add(FString(TEXT("walletAddress=")) + FPlatformHttp::UrlEncode(WalletAddress));
100+
QueryParams.Add(FString(TEXT("themeColor=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetThemeColor().ToString()));
101+
QueryParams.Add(FString(TEXT("isAutoFillUserData=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->IsAutoFillUserData() ? TEXT("true") : TEXT("false")));
102+
QueryParams.Add(FString(TEXT("disableWalletAddressForm=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->IsDisableWalletAddressForm() ? TEXT("true") : TEXT("false")));
103+
104+
if (!OnRampWidgetConfig->GetNetwork().IsEmpty())
105+
{
106+
QueryParams.Add(FString(TEXT("network=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetNetwork()));
107+
}
108+
109+
if (!ProductsAvailed.IsEmpty())
110+
{
111+
QueryParams.Add(FString(TEXT("productsAvailed=")) + FPlatformHttp::UrlEncode(ProductsAvailed));
112+
}
113+
114+
if (!ScreenTitle.IsEmpty())
115+
{
116+
QueryParams.Add(FString(TEXT("exchangeScreenTitle=")) + FPlatformHttp::UrlEncode(ScreenTitle));
117+
}
118+
119+
if (!OnRampWidgetConfig->GetDefaultCryptoCurrency().IsEmpty())
120+
{
121+
QueryParams.Add(FString(TEXT("defaultCryptoCurrency=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetDefaultCryptoCurrency()));
122+
}
123+
124+
if (!OnRampWidgetConfig->GetDefaultFiatAmount().IsEmpty())
125+
{
126+
QueryParams.Add(FString(TEXT("defaultFiatAmount=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetDefaultFiatAmount()));
127+
}
128+
129+
if (!OnRampWidgetConfig->GetDefaultFiatCurrency().IsEmpty())
130+
{
131+
QueryParams.Add(FString(TEXT("defaultFiatCurrency=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetDefaultFiatCurrency()));
132+
}
133+
134+
if (!OnRampWidgetConfig->GetDefaultPaymentMethod().IsEmpty())
135+
{
136+
QueryParams.Add(FString(TEXT("defaultPaymentMethod=")) + FPlatformHttp::UrlEncode(OnRampWidgetConfig->GetDefaultPaymentMethod()));
137+
}
138+
139+
if (OnRampWidgetConfig->GetCryptoCurrencyList().Num() > 0)
140+
{
141+
QueryParams.Add(FString(TEXT("cryptoCurrencyList=")) + FPlatformHttp::UrlEncode(FString::Join(OnRampWidgetConfig->GetCryptoCurrencyList(), TEXT(","))));
142+
}
143+
144+
if (OnRampWidgetConfig->GetDisablePaymentMethods().Num() > 0)
145+
{
146+
QueryParams.Add(FString(TEXT("disablePaymentMethods=")) + FPlatformHttp::UrlEncode(FString::Join(OnRampWidgetConfig->GetDisablePaymentMethods(), TEXT(","))));
147+
}
148+
149+
Path += TEXT("?");
150+
Path += FString::Join(QueryParams, TEXT("&"));
151+
152+
return Path;
153+
}
154+
155+
void UOnRampWidget::HandleOnUrlChanged(const FText& Text)
156+
{
157+
if (Text.EqualToCaseIgnored(FText::FromString(InitialURL)))
158+
{
159+
bIsReady = true;
160+
OnWhenReady.Broadcast();
161+
OnWhenReady.Clear();
162+
}
163+
}
164+
165+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
166+
void UOnRampWidget::HandleOnConsoleMessage(const FString& Message, const FString& Source, int32 Line, EWebBrowserConsoleLogSeverity Severity)
167+
{
168+
UE_LOG(LogImmutableOnRampWidget, Log, TEXT("Web Browser console message: %s, Source: %s, Line: %d"), *Message, *Source, Line);
169+
}
170+
171+
bool UOnRampWidget::HandleOnBeforePopup(FString URL, FString Frame)
172+
{
173+
return false;
174+
}
175+
#endif
176+
177+
#undef LOCTEXT_NAMESPACE
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include "CoreMinimal.h"
4+
#include "Modules/ModuleManager.h"
5+
6+
class FImmutableMarketplaceModule : public IModuleInterface
7+
{
8+
public:
9+
virtual void StartupModule() override;
10+
virtual void ShutdownModule() override;
11+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include "Engine/DeveloperSettings.h"
4+
#include "OnRampWidgetConfig.h"
5+
6+
#include "ImmutableMarketplaceSettings.generated.h"
7+
8+
9+
/**
10+
* Immutable Marketplace developer settings is a configuration class for the ImmutableMarketplace module.
11+
* This class contains settings that can be adjusted to control the behavior
12+
* of the ImmutableMarketplace tools within the Unreal Engine environment.
13+
*/
14+
UCLASS(config = Game, defaultconfig, meta = (DisplayName = "Immutable Marketplace"))
15+
class IMMUTABLEMARKETPLACE_API UImmutableMarketplaceSettings : public UDeveloperSettings
16+
{
17+
GENERATED_BODY()
18+
19+
public:
20+
/// The default on ramp widget configuration class.
21+
/// This property holds a reference to a subclass of UTransakConfig,
22+
/// which is used to load on ramp widget in web browser.
23+
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly)
24+
TSubclassOf<UOnRampWidgetConfig> DefaultOnRampWidgetConfig;
25+
};
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#pragma once
2+
3+
#include "Components/Widget.h"
4+
5+
#include "OnRampWebBrowserWidget.generated.h"
6+
7+
8+
DECLARE_LOG_CATEGORY_EXTERN(LogImmutableOnRampWidget, Log, All);
9+
10+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
11+
enum class EWebBrowserConsoleLogSeverity;
12+
13+
class SWebBrowser;
14+
#else
15+
class SBluWebBrowser;
16+
#endif
17+
18+
19+
/**
20+
* A custom web browser widget for Immutable On Ramp funds transactions.
21+
*/
22+
UCLASS()
23+
class IMMUTABLEMARKETPLACE_API UOnRampWidget : public UWidget
24+
{
25+
GENERATED_BODY()
26+
27+
public:
28+
DECLARE_MULTICAST_DELEGATE(FOnWhenReady);
29+
30+
public:
31+
/**
32+
* Check if the web browser widget is ready to be loaded.
33+
*
34+
* @return True if the widget is ready, false otherwise.
35+
*/
36+
UFUNCTION(BlueprintPure)
37+
bool IsReady() const;
38+
39+
/**
40+
* Loads on ramp widget with provided user data.
41+
*
42+
* @param WalletAddress The wallet address to load.
43+
* @param Email The email associated with the user.
44+
* @param ProductsAvailed The products availed by the user.
45+
* @param ScreenTitle The title of the screen to load.
46+
*/
47+
UFUNCTION(BlueprintCallable)
48+
void Load(const FString& WalletAddress, const FString& Email, const FString& ProductsAvailed, const FString& ScreenTitle);
49+
50+
FDelegateHandle CallAndRegister_OnWhenReady(FOnWhenReady::FDelegate Delegate);
51+
52+
protected:
53+
// UWidget interface
54+
virtual TSharedRef<SWidget> RebuildWidget() override;
55+
// End of UWidget interface
56+
57+
protected:
58+
FString ComputePath(const FString& WalletAddress, const FString& Email, const FString& ProductsAvailed, const FString& ScreenTitle);
59+
60+
void HandleOnUrlChanged(const FText& Text);
61+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
62+
void HandleOnConsoleMessage(const FString& Message, const FString& Source, int32 Line, EWebBrowserConsoleLogSeverity Severity);
63+
bool HandleOnBeforePopup(FString URL, FString Frame);
64+
#endif
65+
66+
protected:
67+
/** URL that the browser will initially navigate to. The URL should include the protocol, eg http:// */
68+
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
69+
FString InitialURL = TEXT("about:blank");
70+
71+
#if (ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1)
72+
TSharedPtr<class SWebBrowser> WebBrowserWidget;
73+
#else
74+
TSharedPtr<SBluWebBrowser> WebBrowserWidget;
75+
#endif
76+
FOnWhenReady OnWhenReady;
77+
78+
protected:
79+
bool bIsReady = false;
80+
};
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#pragma once
2+
3+
#include "OnRampWidgetConfig.generated.h"
4+
5+
6+
UENUM(BlueprintType)
7+
enum class ETransakEnvironment : uint8
8+
{
9+
Sandbox,
10+
Production,
11+
};
12+
13+
/**
14+
* @class UOnRampWidgetConfig
15+
* @brief Configuration settings for on ramp widget.
16+
*/
17+
UCLASS(Abstract, Blueprintable, ClassGroup = Immutable)
18+
class IMMUTABLEMARKETPLACE_API UOnRampWidgetConfig : public UObject
19+
{
20+
GENERATED_BODY()
21+
22+
public:
23+
/**
24+
* Get the URL based on the current environment setting.
25+
* @return The URL corresponding to the current environment setting.
26+
*/
27+
FString GetURL() const
28+
{
29+
switch (Environment)
30+
{
31+
case ETransakEnvironment::Production:
32+
return TEXT("https://global.transak.com/");
33+
default:
34+
case ETransakEnvironment::Sandbox:
35+
return TEXT("https://global-stg.transak.com/");
36+
}
37+
}
38+
39+
/**
40+
* Get the API key based on the current environment.
41+
* @return The API key corresponding to the current environment.
42+
*/
43+
FString GetAPIKey() const
44+
{
45+
switch (Environment)
46+
{
47+
case ETransakEnvironment::Production:
48+
return TEXT("ad1bca70-d917-4628-bb0f-5609537498bc");
49+
default:
50+
case ETransakEnvironment::Sandbox:
51+
return TEXT("d14b44fb-0f84-4db5-affb-e044040d724b");
52+
}
53+
}
54+
55+
/**
56+
* @details More details could be found under the class parameter
57+
* @return Network as FString
58+
*/
59+
const FString& GetNetwork() const
60+
{
61+
return Network;
62+
}
63+
64+
/**
65+
* @details More details could be found under the class parameter
66+
* @return DefaultFiatCurrency as FString
67+
*/
68+
const FString& GetDefaultFiatCurrency() const
69+
{
70+
return DefaultFiatCurrency;
71+
}
72+
73+
/**
74+
* @details More details could be found under the class parameter
75+
* @return DefaultFiatAmount as FString
76+
*/
77+
const FString& GetDefaultFiatAmount() const
78+
{
79+
return DefaultFiatAmount;
80+
}
81+
82+
/**
83+
* @details More details could be found under the class parameter
84+
* @return DefaultCryptoCurrency as FString
85+
*/
86+
const FString& GetDefaultCryptoCurrency() const
87+
{
88+
return DefaultCryptoCurrency;
89+
}
90+
91+
/**
92+
* @details More details could be found under the class parameter
93+
* @return DefaultPaymentMethod as FString
94+
*/
95+
const FString& GetDefaultPaymentMethod() const
96+
{
97+
return DefaultPaymentMethod;
98+
}
99+
100+
/**
101+
* @details More details could be found under the class parameter
102+
* @return DisablePaymentMethods as array of FString
103+
*/
104+
const TArray<FString>& GetDisablePaymentMethods() const
105+
{
106+
return DisablePaymentMethods;
107+
}
108+
109+
/**
110+
* @details More details could be found under the class parameter
111+
* @return bIsAutoFillUserData as bool
112+
*/
113+
bool IsAutoFillUserData() const
114+
{
115+
return bIsAutoFillUserData;
116+
}
117+
118+
/**
119+
* @details More details could be found under the class parameter
120+
* @return bDisableWalletAddressForm as bool
121+
*/
122+
bool IsDisableWalletAddressForm() const
123+
{
124+
return bDisableWalletAddressForm;
125+
}
126+
127+
/**
128+
* @details More details could be found under the class parameter
129+
* @return CryptoCurrencyList as array of FString
130+
*/
131+
const TArray<FString>& GetCryptoCurrencyList() const
132+
{
133+
return CryptoCurrencyList;
134+
}
135+
136+
/**
137+
* @details More details could be found under the class parameter
138+
* @return ThemeColor as FLinearColor
139+
*/
140+
const FLinearColor& GetThemeColor() const
141+
{
142+
return ThemeColor;
143+
}
144+
145+
protected:
146+
/**
147+
* Specifies the environment for transactions.
148+
* @note The default environment is set to the Sandbox environment.
149+
*/
150+
UPROPERTY(EditDefaultsOnly, Category = "General")
151+
ETransakEnvironment Environment = ETransakEnvironment::Sandbox;
152+
153+
/**
154+
* The default payment method you would prefer the customer to buy/sell with.
155+
* If you pass this param, the payment method will be selected by default and the customer can
156+
* also select another payment method.
157+
*/
158+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
159+
FString DefaultPaymentMethod;
160+
161+
/**
162+
* The three letter code of the fiat currency your user will send/receive while buying/selling cryptocurrency.
163+
* Users can change the fiat currency if this is passed. If the fiat currency is not supported by
164+
* a specific product type (BUY/SELL) then the default widget will load with all the supported fiat
165+
* currencies for that product type.
166+
*/
167+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
168+
FString DefaultFiatCurrency;
169+
170+
/**
171+
* An integer amount representing how much the customer wants to spend/receive.
172+
* Users can change the fiat amount if this is passed.
173+
*/
174+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
175+
FString DefaultFiatAmount;
176+
177+
/**
178+
* The default cryptocurrency you would prefer the customer to buy/sell.
179+
* If you pass this param, the currency will be selected by default, but the customer will
180+
* still be able to select another cryptocurrency. Please ensure that the currency code passed by
181+
* you is available for the specific product type (BUY/SELL).
182+
* If you pass a value that is not supported by BUY/SELL, then the default widget will load.
183+
*/
184+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
185+
FString DefaultCryptoCurrency;
186+
187+
/**
188+
* Crypto network that you would allow your customers to buy.
189+
* You can get the supporting networks by opening http://global.transak.com and then go to
190+
* cryptocurrencies select screen. Only the cryptocurrencies supported by this network for
191+
* the specific product type (BUY/SELL) will be shown in the widget.
192+
* If the network selected is not supported by a product type (BUY/SELL) then the default widget will
193+
* all supported networks will be shown.
194+
*/
195+
UPROPERTY(EditDefaultsOnly, Category = "Blockchain")
196+
FString Network;
197+
198+
/**
199+
* A comma-separated list of payment methods you want to disable and hide from the customers.
200+
* Refer here to the list of supported params for the payment method.
201+
*/
202+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
203+
TArray<FString> DisablePaymentMethods;
204+
205+
/**
206+
* When true, then the email address will be auto-filled, but the screen will not be skipped.
207+
* User can edit their email address, basic data like first name & the address.
208+
* This parameter will be ignored if email or userData are not passed.
209+
*/
210+
UPROPERTY(EditDefaultsOnly, Category = "User")
211+
bool bIsAutoFillUserData = true;
212+
213+
/**
214+
* When true, the customer will not be able to change the destination address of
215+
* where the cryptocurrency is sent to.
216+
*/
217+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
218+
bool bDisableWalletAddressForm = true;
219+
220+
/**
221+
* A comma-separated list of cryptoCurrencies that you would allow your customers to buy/sell.
222+
* Only these crypto currencies will be shown in the widget. This will be a string of comma
223+
* separated values each of which will represent a valid cryptoCurrency code.
224+
* Please ensure that the crypto currency codes passed in the list are available for the specific
225+
* product type (BUY/SELL). If even one of the crypto currency codes in the list is supported by
226+
* the specific product type (BUY/SELL), then it will be honored, otherwise the default widget will
227+
* load for the product type for which none of the crypto currency codes are supported.
228+
*/
229+
UPROPERTY(EditDefaultsOnly, Category = "Fiat")
230+
TArray<FString> CryptoCurrencyList;
231+
232+
/**
233+
* The theme color code for the widget main color. It is used for buttons,
234+
*/
235+
UPROPERTY(EditDefaultsOnly, Category = "Theme")
236+
FLinearColor ThemeColor;
237+
};

0 commit comments

Comments
 (0)
Please sign in to comment.