diff --git a/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset b/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset
index 0548998d..f6a40f5d 100644
Binary files a/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset and b/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset differ
diff --git a/Content/BlueprintSampleContent/ImtblEvmSignTypedDataWidget4_27.uasset b/Content/BlueprintSampleContent/ImtblEvmSignTypedDataWidget4_27.uasset
new file mode 100644
index 00000000..044339d7
Binary files /dev/null and b/Content/BlueprintSampleContent/ImtblEvmSignTypedDataWidget4_27.uasset differ
diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.cpp
new file mode 100644
index 00000000..67f79b30
--- /dev/null
+++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.cpp
@@ -0,0 +1,53 @@
+#include "Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.h"
+
+#include "Immutable/ImmutablePassport.h"
+#include "Immutable/ImmutableSubsystem.h"
+#include "Immutable/Misc/ImtblLogging.h"
+
+
+UImtblPassportZkEvmSignTypedDataV4AsyncAction* UImtblPassportZkEvmSignTypedDataV4AsyncAction::ZkEvmSignTypedDataV4(UObject* WorldContextObject, const FString& JsonStringRequest)
+{
+	UImtblPassportZkEvmSignTypedDataV4AsyncAction* PassportZkEvmSignTypedDataV4BlueprintNode = NewObject<UImtblPassportZkEvmSignTypedDataV4AsyncAction>();
+	
+	PassportZkEvmSignTypedDataV4BlueprintNode->WorldContextObject = WorldContextObject;
+	PassportZkEvmSignTypedDataV4BlueprintNode->JsonStringSignRequest = JsonStringRequest;
+
+	return PassportZkEvmSignTypedDataV4BlueprintNode;
+}
+
+void UImtblPassportZkEvmSignTypedDataV4AsyncAction::Activate()
+{
+	if (!WorldContextObject || !WorldContextObject->GetWorld())
+	{
+		FString Err = "zkEVM Sign Typed Data V4 failed due to missing world or world " "context object.";
+		IMTBL_WARN("%s", *Err)
+		Failed.Broadcast(Err, TEXT(""));
+		return;
+	}
+
+	GetSubsystem()->WhenReady(this, &UImtblPassportZkEvmSignTypedDataV4AsyncAction::DoZkEvmSignTypedDataV4);
+}
+
+void UImtblPassportZkEvmSignTypedDataV4AsyncAction::DoZkEvmSignTypedDataV4(TWeakObjectPtr<UImtblJSConnector> JSConnector)
+{
+	auto Passport = GetSubsystem()->GetPassport();
+
+	if (Passport.IsValid())
+	{
+		Passport->ZkEvmSignTypedDataV4(JsonStringSignRequest, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportZkEvmSignTypedDataV4AsyncAction::OnZkEvmSignTypedDataV4Response));
+	}
+}
+
+void UImtblPassportZkEvmSignTypedDataV4AsyncAction::OnZkEvmSignTypedDataV4Response(FImmutablePassportResult Result)
+{
+	if (Result.Success)
+	{
+		IMTBL_LOG("zkEVM Sign Typed Data V4 success")
+		MessageSigned.Broadcast(TEXT(""), UImmutablePassport::GetResponseResultAsString(Result.Response));
+	}
+	else
+	{
+		IMTBL_LOG("zkEVM Sign Typed Data V4 failed")
+		Failed.Broadcast(Result.Error, TEXT(""));
+	}
+}
diff --git a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
index ff6c4ab8..b70e6e20 100644
--- a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
+++ b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp
@@ -130,6 +130,11 @@ void UImmutablePassport::ZkEvmGetTransactionReceipt(const FZkEvmTransactionRecei
 	CallJS(ImmutablePassportAction::ZkEvmGetTransactionReceipt, UStructToJsonString(Request), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnBridgeCallbackResponse));
 }
 
+void UImmutablePassport::ZkEvmSignTypedDataV4(const FString& RequestJsonString, const FImtblPassportResponseDelegate& ResponseDelegate)
+{
+	CallJS(ImmutablePassportAction::ZkEvmSignTypedDataV4, RequestJsonString, ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnBridgeCallbackResponse));
+}
+
 void UImmutablePassport::ConfirmCode(const FString& DeviceCode, const float Interval, const FImtblPassportResponseDelegate& ResponseDelegate)
 {
 	FImmutablePassportCodeConfirmRequestData Data{DeviceCode, Interval};
diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.h
new file mode 100644
index 00000000..cd11b982
--- /dev/null
+++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportZkEvmSignTypedDataV4AsyncAction.h
@@ -0,0 +1,35 @@
+#pragma once
+
+
+#include "Immutable/ImmutablePassport.h"
+#include "ImtblBlueprintAsyncAction.h"
+
+#include "ImtblPassportZkEvmSignTypedDataV4AsyncAction.generated.h"
+
+/**
+ * Async action blueprint node for zkEVM SignTypedDataV4
+ */
+UCLASS()
+class IMMUTABLE_API UImtblPassportZkEvmSignTypedDataV4AsyncAction : public UImtblBlueprintAsyncAction
+{
+	GENERATED_BODY()
+
+	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPassportZkEvmSignTypedDataV4OutputPin, FString, ErrorMessage, FString, Signature);
+
+public:
+	UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable")
+	static UImtblPassportZkEvmSignTypedDataV4AsyncAction* ZkEvmSignTypedDataV4(UObject* WorldContextObject, const FString& JsonStringRequest);
+
+	virtual void Activate() override;
+
+private:
+	FString JsonStringSignRequest;
+
+	UPROPERTY(BlueprintAssignable)
+	FPassportZkEvmSignTypedDataV4OutputPin MessageSigned;
+	UPROPERTY(BlueprintAssignable)
+	FPassportZkEvmSignTypedDataV4OutputPin Failed;
+
+	void DoZkEvmSignTypedDataV4(TWeakObjectPtr<class UImtblJSConnector> JSGetConnector);
+	void OnZkEvmSignTypedDataV4Response(FImmutablePassportResult Result);
+};
diff --git a/Source/Immutable/Public/Immutable/ImmutableNames.h b/Source/Immutable/Public/Immutable/ImmutableNames.h
index 8e87a6c6..7183e94a 100644
--- a/Source/Immutable/Public/Immutable/ImmutableNames.h
+++ b/Source/Immutable/Public/Immutable/ImmutableNames.h
@@ -16,6 +16,7 @@ namespace ImmutablePassportAction
 	const FString ZkEvmSendTransaction = TEXT("zkEvmSendTransaction");
 	const FString zkEvmSendTransactionWithConfirmation = TEXT("zkEvmSendTransactionWithConfirmation");
 	const FString ZkEvmGetTransactionReceipt = TEXT("zkEvmGetTransactionReceipt");
+	const FString ZkEvmSignTypedDataV4 = TEXT("zkEvmSignTypedDataV4");
 
 #if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC
 	const FString GetPKCEAuthUrl = TEXT("getPKCEAuthUrl");
diff --git a/Source/Immutable/Public/Immutable/ImmutablePassport.h b/Source/Immutable/Public/Immutable/ImmutablePassport.h
index 5a555d8d..a7a2fda4 100644
--- a/Source/Immutable/Public/Immutable/ImmutablePassport.h
+++ b/Source/Immutable/Public/Immutable/ImmutablePassport.h
@@ -4,7 +4,6 @@
 
 #include "CoreMinimal.h"
 #include "JsonObjectConverter.h"
-#include "Misc/EngineVersion.h"
 #include "Runtime/Core/Public/HAL/Platform.h"
 #include "UObject/Object.h"
 #include "Immutable/ImtblJSConnector.h"
@@ -164,6 +163,16 @@ class IMMUTABLE_API UImmutablePassport : public UObject
 	 * FImtblPassportResponseDelegate to call on response from JS.
 	 */
 	void ZkEvmGetTransactionReceipt(const FZkEvmTransactionReceiptRequest& Request, const FImtblPassportResponseDelegate& ResponseDelegate);
+
+	/**
+	 * Generate a signature for a typed data V4 object
+	 * Signs the EIP-712 structured message in JSON string format using the logged-in Passport account.
+	 * @see https://eips.ethereum.org/EIPS/eip-712
+	 * @param RequestJsonString The EIP-712 structured data in JSON string format
+	 * @param ResponseDelegate The response delegate of type
+	 * FImtblPassportResponseDelegate to call on response from JS.
+	 */
+	void ZkEvmSignTypedDataV4(const FString& RequestJsonString, const FImtblPassportResponseDelegate& ResponseDelegate);
 	
 	/**
 	 * Gets the currently saved ID token without verifying its validity.