From 4f8efa2d9432da3d7a9c43c139c3d69524fe3a22 Mon Sep 17 00:00:00 2001
From: YermekG <yermek.garifullanov@immutable.com>
Date: Thu, 7 Nov 2024 01:13:48 +1300
Subject: [PATCH 1/2] feat: added utilities to simplify managing immutable
 configurations

---
 Source/Immutable/Immutable.Build.cs           |   1 +
 .../Private/Immutable/ImmutablePassport.cpp   |  31 ++++
 .../Private/Immutable/ImmutableUtilities.cpp  |  13 ++
 .../Public/Immutable/ApplicationConfig.h      | 162 ++++++++++++++++++
 .../Public/Immutable/ImmutablePassport.h      |   9 +
 .../Immutable/ImmutablePluginSettings.h       |  21 +++
 .../Public/Immutable/ImmutableUtilities.h     |   3 +
 7 files changed, 240 insertions(+)
 create mode 100644 Source/Immutable/Public/Immutable/ApplicationConfig.h
 create mode 100644 Source/Immutable/Public/Immutable/ImmutablePluginSettings.h

diff --git a/Source/Immutable/Immutable.Build.cs b/Source/Immutable/Immutable.Build.cs
index 4fb2b26..a5317f2 100644
--- a/Source/Immutable/Immutable.Build.cs
+++ b/Source/Immutable/Immutable.Build.cs
@@ -33,6 +33,7 @@ public Immutable(ReadOnlyTargetRules Target) : base(Target)
                 "Json",
                 "UMG",
                 "Projects", 
+                "DeveloperSettings",
 			}
         );
 
diff --git a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
index b70e6e2..708f6ef 100644
--- a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
+++ b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
@@ -8,6 +8,7 @@
 #include "Immutable/ImtblJSConnector.h"
 #include "JsonObjectConverter.h"
 #include "Immutable/ImmutableSaveGame.h"
+#include "Immutable/ImmutableUtilities.h"
 #include "Kismet/GameplayStatics.h"
 #include "Policies/CondensedJsonPrintPolicy.h"
 
@@ -45,6 +46,36 @@ void UImmutablePassport::Initialize(const FImmutablePassportInitData& Data, cons
 	CallJS(ImmutablePassportAction::INIT, InitData.ToJsonString(), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnInitializeResponse), false);
 }
 
+void UImmutablePassport::Initialize(const FImtblPassportResponseDelegate& ResponseDelegate)
+{
+	check(JSConnector.IsValid());
+	
+	UApplicationConfig* ApplicationConfig = FImmutableUtilities::GetDefaultApplicationConfig();
+
+	if (!ApplicationConfig)
+	{
+		ResponseDelegate.ExecuteIfBound(FImmutablePassportResult{false, "Failed to retrieve default application configuration for Passport initialization"});
+
+		return;
+	}
+
+	InitData.clientId = ApplicationConfig->GetClientID();
+	InitData.environment = ApplicationConfig->GetEnvironment();
+	InitData.redirectUri = ApplicationConfig->GetRedirectURL();
+	InitData.logoutRedirectUri = ApplicationConfig->GetLogoutURL();
+
+	LoadPassportSettings();
+	// we check saved settings in case if player has not logged out properly
+	if (InitData.logoutRedirectUri.IsEmpty() && IsStateFlagsSet(IPS_PKCE))
+	{
+		IMTBL_ERR("Logout URI is empty. Previously logged in via PKCE.")
+		ResetStateFlags(IPS_PKCE);
+		SavePassportSettings();
+	}
+
+	CallJS(ImmutablePassportAction::INIT, InitData.ToJsonString(), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnInitializeResponse), false);
+}
+
 void UImmutablePassport::Connect(bool IsConnectImx, bool TryToRelogin, const FImtblPassportResponseDelegate& ResponseDelegate)
 {
 	SetStateFlags(IPS_CONNECTING);
diff --git a/Source/Immutable/Private/Immutable/ImmutableUtilities.cpp b/Source/Immutable/Private/Immutable/ImmutableUtilities.cpp
index 8325b60..a81db18 100644
--- a/Source/Immutable/Private/Immutable/ImmutableUtilities.cpp
+++ b/Source/Immutable/Private/Immutable/ImmutableUtilities.cpp
@@ -1,5 +1,6 @@
 #include "Immutable/ImmutableUtilities.h"
 
+#include "Immutable/ImmutablePluginSettings.h"
 #include "Immutable/Misc/ImtblLogging.h"
 #include "Interfaces/IPluginManager.h"
 #include "Misc/FileHelper.h"
@@ -19,3 +20,15 @@ bool FImmutableUtilities::LoadGameBridge(FString& GameBridge)
 
 	return false;
 }
+
+UApplicationConfig* FImmutableUtilities::GetDefaultApplicationConfig()
+{
+	auto Settings = GetDefault<UImmutablePluginSettings>();
+
+	if (!Settings)
+	{
+		return nullptr;
+	}
+
+	return Settings->DefaultApplicationConfig.GetDefaultObject();
+}
diff --git a/Source/Immutable/Public/Immutable/ApplicationConfig.h b/Source/Immutable/Public/Immutable/ApplicationConfig.h
new file mode 100644
index 0000000..ad46fea
--- /dev/null
+++ b/Source/Immutable/Public/Immutable/ApplicationConfig.h
@@ -0,0 +1,162 @@
+#pragma once
+
+#include "ApplicationConfig.generated.h"
+
+/**
+ * @class UApplicationConfig
+ * @brief Configuration settings for Passport and various APIs.
+ * @details This class stores configuration settings such as URLs, chain names, contract addresses, 
+ * client IDs, and environment settings for the zkEVM API, Orderbook API, and Passport.
+ */
+UCLASS(Abstract, Blueprintable, ClassGroup = Immutable)
+class UApplicationConfig : public UObject
+{
+	GENERATED_BODY()
+
+public:
+	/**
+	 * Retrieves URL for the zkEVM API.
+	 *
+	 * @return A constant reference to an FString containing the name of the chain.
+	 */
+	const FString& GetzkEVMAPIURL()
+	{
+		return zkEVMAPIURL;
+	}
+	
+	/**
+	 * Retrieves the name of the chain used to pass to the zkEVM API.
+	 *
+	 * @return A constant reference to an FString containing the name of the chain.
+	 */
+	const FString& GetzkEVMAPIChainName()
+	{
+		return zkEVMAPIChainName;
+	}
+
+	/**
+	 * Retrieves URL for the Orderbook API.
+	 *
+	 * @return A constant reference to an FString containing the name of the chain.
+	 */
+	const FString& GetOrderbookAPIURL()
+	{
+		return OrederbookAPIURL;
+	}
+	
+	/**
+	 * Retrieves the name of the chain used to pass to the Orderbook API.
+	 *
+	 * @return A constant reference to an FString containing the name of the chain.
+	 */
+	const FString& GetOrderbookAPIChainName()
+	{
+		return OrderbookAPIChainName;
+	}
+
+	/**
+	 * @brief Retrieves the cryptocurrency contract address associated with the user's wallet balance.
+	 *
+	 * @return A string representing the contract address.
+	 */
+	const FString& GetTokenBalanceContractAddress()
+	{
+		return TokenBalanceContractAddress;
+	} 
+
+	/**
+	 * Retrieves the list of NFT contracts used in the APIs' queries.
+	 *
+	 * @return A constant reference to an array of strings representing the contracts.
+	 */
+	const TArray<FString>& GetNFTContractAddresses()
+	{
+		return NFTContractAddress;
+	}
+
+	/**
+	 * Retrieves the Client ID used for Passport initialization.
+	 *
+	 * @return A constant reference to an FString containing the Client ID.
+	 */
+	const FString& GetClientID()
+	{
+		return ClientID;	
+	}
+
+	/**
+	 * Retrieves the environment configuration used for Passport initialization.
+	 *
+	 * @return A constant reference to an FString representing the environment.
+	 */
+	const FString& GetEnvironment()
+	{
+		return Environment;
+	}
+
+	/**
+	 * Retrieves the URL where the browser will redirect after successful authentication.
+	 * @note This is only used for Android, iOS, and macOS.
+	 *
+	 * @return A constant reference to an FString containing the redirect URL.
+	 */
+	const FString& GetRedirectURL()
+	{
+		return RedirectURL;
+	}
+
+	/**
+	 * Retrieves the URL used for logging out.
+	 *
+	 * @return A constant reference to an FString containing the logout URL.
+	 */
+	const FString& GetLogoutURL()
+	{
+		return LogoutURL;
+	}
+
+protected:
+	/** The URL for the zkEVM API. */
+	UPROPERTY(EditDefaultsOnly, Category = "zkEVM API")
+	FString zkEVMAPIURL;
+
+	/** The name of the API chain used by the zkEVM API. */
+	UPROPERTY(EditDefaultsOnly, Category = "zkEVM API")
+	FString zkEVMAPIChainName;
+
+	/** The URL for the Orderbook API. */
+	UPROPERTY(EditDefaultsOnly, Category = "Orderbook API")
+	FString OrederbookAPIURL;
+
+	/** The name of the API chain used by Orderbook API. */
+	UPROPERTY(EditDefaultsOnly, Category = "Orderbook API")
+	FString OrderbookAPIChainName;
+	
+	/** The address of the cryptocurrency contract in the blockchain. */
+	UPROPERTY(EditDefaultsOnly, Category = "Contracts")
+	FString TokenBalanceContractAddress;
+
+	/** An array of NFT contract addresses used for searching NFTs in the marketplace or displaying them in the player's inventory. */
+	UPROPERTY(EditDefaultsOnly, Category = "Contracts")
+	TArray<FString> NFTContractAddress;
+
+	/** Passport Client ID. */
+	UPROPERTY(EditDefaultsOnly, Category = "Passport")
+	FString ClientID;
+
+	/** Environment used to initialize passport. Ex. sandbox or production */
+	UPROPERTY(EditDefaultsOnly, Category = "Passport")
+	FString Environment;
+
+	/**
+	 * (Android, iOS, and macOS only)
+	 * The URL where the browser will redirect after successful authentication.
+	 */
+	UPROPERTY(EditDefaultsOnly, Category = "Passport")
+	FString RedirectURL;
+
+	/** The URL where the browser will redirect after logout is complete. */
+	UPROPERTY(EditDefaultsOnly, Category = "Passport")
+	FString LogoutURL;
+	
+};
diff --git a/Source/Immutable/Public/Immutable/ImmutablePassport.h b/Source/Immutable/Public/Immutable/ImmutablePassport.h
index a7a2fda..13b5cc5 100644
--- a/Source/Immutable/Public/Immutable/ImmutablePassport.h
+++ b/Source/Immutable/Public/Immutable/ImmutablePassport.h
@@ -80,6 +80,15 @@ class IMMUTABLE_API UImmutablePassport : public UObject
 	 */
 	void Initialize(const FImmutablePassportInitData& InitData, const FImtblPassportResponseDelegate& ResponseDelegate);
 
+	/**
+	 * Initialises passport. This sets up the Passport instance, configures the web browser, and waits for the ready signal.
+	 * @details The functionality is the same with Initilize above except it obtains Passport initilization data from ApplicationConfig asset
+	 * @see UApplicationConfig
+	 *
+	 * @param ResponseDelegate 	Callback delegate.
+	 */
+	void Initialize(const FImtblPassportResponseDelegate& ResponseDelegate);
+
 	/**
 	 * Logs the user into Passport via device code auth and sets up the Immutable X provider.
 	 *
diff --git a/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h b/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h
new file mode 100644
index 0000000..ba87905
--- /dev/null
+++ b/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "Engine/DeveloperSettings.h"
+#include "ApplicationConfig.h"
+
+#include "ImmutablePluginSettings.generated.h"
+
+
+/**
+ * 
+ */
+UCLASS(config = Game, defaultconfig, meta = (DisplayName = "Immutable Plugin Settings"))
+class IMMUTABLE_API UImmutablePluginSettings : public UDeveloperSettings
+{
+	GENERATED_BODY()
+
+public:
+	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "General")
+	TSubclassOf<UApplicationConfig> DefaultApplicationConfig;
+
+};
diff --git a/Source/Immutable/Public/Immutable/ImmutableUtilities.h b/Source/Immutable/Public/Immutable/ImmutableUtilities.h
index d13015d..45af345 100644
--- a/Source/Immutable/Public/Immutable/ImmutableUtilities.h
+++ b/Source/Immutable/Public/Immutable/ImmutableUtilities.h
@@ -1,4 +1,5 @@
 #pragma once
+#include "ApplicationConfig.h"
 
 
 /** A wrapper struct around various Immutable namespace utility and support methods. */
@@ -12,4 +13,6 @@ struct IMMUTABLE_API FImmutableUtilities
 	 * @return True if the game bridge content was sucessfully retrieved. Otherwise, false.
 	 */
 	static bool LoadGameBridge(FString& GameBridge);
+
+	static UApplicationConfig* GetDefaultApplicationConfig();
 };

From a3d96f0dcd2c446783e5e2a1ad50985e6373e783 Mon Sep 17 00:00:00 2001
From: YermekG <yermek.garifullanov@immutable.com>
Date: Thu, 7 Nov 2024 09:31:59 +1300
Subject: [PATCH 2/2] chore: added missing commets

---
 .../Immutable/Public/Immutable/ImmutablePluginSettings.h  | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h b/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h
index ba87905..fd87515 100644
--- a/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h
+++ b/Source/Immutable/Public/Immutable/ImmutablePluginSettings.h
@@ -7,7 +7,9 @@
 
 
 /**
- * 
+ * ImmutablePluginSettings is a configuration class for the Immutable plugin.
+ * This class contains settings that can be adjusted to control the behavior
+ * of the Immutable plugin within the Unreal Engine environment.
  */
 UCLASS(config = Game, defaultconfig, meta = (DisplayName = "Immutable Plugin Settings"))
 class IMMUTABLE_API UImmutablePluginSettings : public UDeveloperSettings
@@ -15,7 +17,9 @@ class IMMUTABLE_API UImmutablePluginSettings : public UDeveloperSettings
 	GENERATED_BODY()
 
 public:
+	/// The default application configuration class.
+	/// This property holds a reference to a subclass of UApplicationConfig,
+	/// which will be used as the default configuration for the application.
 	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "General")
 	TSubclassOf<UApplicationConfig> DefaultApplicationConfig;
-
 };