diff --git a/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset b/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset index 621518ca..0548998d 100644 Binary files a/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset and b/Content/BlueprintSampleContent/ImtblAuthenticatedWidget4_26.uasset differ diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.cpp deleted file mode 100644 index 083e7104..00000000 --- a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#include "Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.h" - -#include "Immutable/ImmutablePassport.h" -#include "Immutable/ImmutableSubsystem.h" -#include "Immutable/Misc/ImtblLogging.h" - -UImtblPassportGetAccessTokenAsyncAction* UImtblPassportGetAccessTokenAsyncAction::GetAccessToken(UObject* WorldContextObject) -{ - UImtblPassportGetAccessTokenAsyncAction* PassportInitBlueprintNode = NewObject(); - PassportInitBlueprintNode->WorldContextObject = WorldContextObject; - return PassportInitBlueprintNode; -} - -void UImtblPassportGetAccessTokenAsyncAction::Activate() -{ - if (!WorldContextObject || !WorldContextObject->GetWorld()) - { - FString Err = "GetAccessToken failed due to missing world or world context object."; - IMTBL_WARN("%s", *Err) - Failed.Broadcast(Err, TEXT("")); - return; - } - - GetSubsystem()->WhenReady(this, &UImtblPassportGetAccessTokenAsyncAction::DoGetAccessToken); -} - -void UImtblPassportGetAccessTokenAsyncAction::DoGetAccessToken(TWeakObjectPtr JSConnector) -{ - // Get Passport - auto Passport = GetSubsystem()->GetPassport(); - // Run GetAccessToken - Passport->GetAccessToken(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetAccessTokenAsyncAction::OnGetAccessTokenResponse)); -} - -void UImtblPassportGetAccessTokenAsyncAction::OnGetAccessTokenResponse(FImmutablePassportResult Result) -{ - if (Result.Success) - { - GotAccessToken.Broadcast(TEXT(""), UImmutablePassport::GetResponseResultAsString(Result.Response)); - } - else - { - Failed.Broadcast(Result.Error, TEXT("")); - } -} diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.cpp deleted file mode 100644 index 1728e9f7..00000000 --- a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#include "Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.h" - -#include "Immutable/ImmutablePassport.h" -#include "Immutable/ImmutableSubsystem.h" -#include "Immutable/Misc/ImtblLogging.h" - -UImtblPassportGetIdTokenAsyncAction* UImtblPassportGetIdTokenAsyncAction::GetIdToken(UObject* WorldContextObject) -{ - UImtblPassportGetIdTokenAsyncAction* PassportInitBlueprintNode = NewObject(); - PassportInitBlueprintNode->WorldContextObject = WorldContextObject; - return PassportInitBlueprintNode; -} - -void UImtblPassportGetIdTokenAsyncAction::Activate() -{ - if (!WorldContextObject || !WorldContextObject->GetWorld()) - { - FString Err = "GetIdToken failed due to missing world or world context object."; - IMTBL_WARN("%s", *Err) - Failed.Broadcast(Err, TEXT("")); - return; - } - - GetSubsystem()->WhenReady(this, &UImtblPassportGetIdTokenAsyncAction::DoGetIdToken); -} - -void UImtblPassportGetIdTokenAsyncAction::DoGetIdToken(TWeakObjectPtr JSConnector) -{ - // Get Passport - auto Passport = GetSubsystem()->GetPassport(); - // Run GetIdToken - Passport->GetIdToken(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetIdTokenAsyncAction::OnGetIdTokenResponse)); -} - -void UImtblPassportGetIdTokenAsyncAction::OnGetIdTokenResponse(FImmutablePassportResult Result) -{ - if (Result.Success) - { - GotIdToken.Broadcast(TEXT(""), UImmutablePassport::GetResponseResultAsString(Result.Response)); - } - else - { - Failed.Broadcast(Result.Error, TEXT("")); - } -} diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.cpp new file mode 100644 index 00000000..fa3abb22 --- /dev/null +++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.cpp @@ -0,0 +1,53 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.h" + +#include "Immutable/ImmutablePassport.h" +#include "Immutable/ImmutableSubsystem.h" +#include "Immutable/Misc/ImtblLogging.h" + +UImtblPassportGetLinkedAddressesAsyncAction* UImtblPassportGetLinkedAddressesAsyncAction::GetLinkedAddresses(UObject* WorldContextObject) +{ + UImtblPassportGetLinkedAddressesAsyncAction* Node = NewObject(); + + Node->WorldContextObject = WorldContextObject; + + return Node; +} + +void UImtblPassportGetLinkedAddressesAsyncAction::Activate() +{ + if (!WorldContextObject || !WorldContextObject->GetWorld()) + { + FString Err = "GetLinkedAddresses failed due to missing world or world context object."; + + IMTBL_WARN("%s", *Err) + Failed.Broadcast(Err, TArray()); + + return; + } + + GetSubsystem()->WhenReady(this, &UImtblPassportGetLinkedAddressesAsyncAction::DoGetLinkedAddresses); +} + +void UImtblPassportGetLinkedAddressesAsyncAction::DoGetLinkedAddresses(TWeakObjectPtr JSConnector) +{ + auto Passport = GetSubsystem()->GetPassport(); + + if (Passport.IsValid()) + { + Passport->GetLinkedAddresses(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetLinkedAddressesAsyncAction::OnGetLinkedAddressesResponse)); + } +} + +void UImtblPassportGetLinkedAddressesAsyncAction::OnGetLinkedAddressesResponse(FImmutablePassportResult Result) +{ + if (Result.Success) + { + Success.Broadcast(TEXT(""), UImmutablePassport::GetResponseResultAsStringArray(Result.Response)); + } + else + { + Failed.Broadcast(Result.Error, TArray()); + } +} diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetTokenAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetTokenAsyncAction.cpp new file mode 100644 index 00000000..6a70b9ce --- /dev/null +++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportGetTokenAsyncAction.cpp @@ -0,0 +1,71 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#include "Immutable/Actions/ImtblPassportGetTokenAsyncAction.h" + +#include "Immutable/ImmutablePassport.h" +#include "Immutable/ImmutableSubsystem.h" +#include "Immutable/Misc/ImtblLogging.h" + +UImtblPassportGetTokenAsyncAction* UImtblPassportGetTokenAsyncAction::GetAccessToken(UObject* WorldContextObject) +{ + UImtblPassportGetTokenAsyncAction* Node = NewObject(); + + Node->WorldContextObject = WorldContextObject; + Node->Type = ACCESS; + + return Node; +} + +UImtblPassportGetTokenAsyncAction* UImtblPassportGetTokenAsyncAction::GetIdToken(UObject* WorldContextObject) +{ + UImtblPassportGetTokenAsyncAction* Node = NewObject(); + + Node->WorldContextObject = WorldContextObject; + Node->Type = ID; + + return Node; +} + +void UImtblPassportGetTokenAsyncAction::Activate() +{ + if (!WorldContextObject || !WorldContextObject->GetWorld()) + { + FString Err = "Get Token failed due to missing world or world context object."; + IMTBL_WARN("%s", *Err) + Failed.Broadcast(Err, TEXT("")); + return; + } + + + GetSubsystem()->WhenReady(this, &UImtblPassportGetTokenAsyncAction::DoGetToken); +} + +void UImtblPassportGetTokenAsyncAction::DoGetToken(TWeakObjectPtr JSConnector) +{ + auto Passport = GetSubsystem()->GetPassport(); + + if (Passport.IsValid()) + { + switch(Type) + { + case ID: + Passport->GetIdToken(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetTokenAsyncAction::OnGetTokenResponse)); + break; + case ACCESS: + Passport->GetAccessToken(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetTokenAsyncAction::OnGetTokenResponse)); + break; + } + } +} + +void UImtblPassportGetTokenAsyncAction::OnGetTokenResponse(FImmutablePassportResult Result) +{ + if (Result.Success) + { + Success.Broadcast(TEXT(""), UImmutablePassport::GetResponseResultAsString(Result.Response)); + } + else + { + Failed.Broadcast(Result.Error, TEXT("")); + } +} diff --git a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp index 371fc9c3..6be65c2e 100644 --- a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp +++ b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp @@ -158,6 +158,11 @@ void UImmutablePassport::GetEmail(const FImtblPassportResponseDelegate& Response CallJS(ImmutablePassportAction::GetEmail, TEXT(""), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnBridgeCallbackResponse)); } +void UImmutablePassport::GetLinkedAddresses(const FImtblPassportResponseDelegate& ResponseDelegate) +{ + CallJS(ImmutablePassportAction::GetLinkedAddresses, TEXT(""), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnBridgeCallbackResponse)); +} + void UImmutablePassport::ImxTransfer(const FImxTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate) { IMTBL_LOG("Tranfer Request: %s", *UStructToJsonString(RequestData)) @@ -223,7 +228,6 @@ FString UImmutablePassport::GetResponseResultAsString(const FImtblJSResponse& Re } return Response.JsonObject->GetStringField(TEXT("result")); - } bool UImmutablePassport::GetResponseResultAsBool(const FImtblJSResponse& Response) @@ -238,6 +242,25 @@ bool UImmutablePassport::GetResponseResultAsBool(const FImtblJSResponse& Respons return Response.JsonObject->GetBoolField(TEXT("result")); } +TArray UImmutablePassport::GetResponseResultAsStringArray(const FImtblJSResponse& Response) +{ + if (!Response.JsonObject.IsValid()) + { + IMTBL_ERR("Response JSON data for %s is not valid", *Response.responseFor) + + return TArray(); + } + + TArray StringArray; + + for (const TSharedPtr& Value : Response.JsonObject->GetArrayField(TEXT("result"))) + { + StringArray.Add(Value->AsString()); + } + + return StringArray; +} + void UImmutablePassport::Setup(const TWeakObjectPtr Connector) { diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.h deleted file mode 100644 index ce75dd7d..00000000 --- a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetAccessTokenAsyncAction.h +++ /dev/null @@ -1,34 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Immutable/ImmutablePassport.h" -#include "ImtblBlueprintAsyncAction.h" -#include "ImtblPassportGetAccessTokenAsyncAction.generated.h" - -/** - * - */ -UCLASS() -class IMMUTABLE_API UImtblPassportGetAccessTokenAsyncAction : public UImtblBlueprintAsyncAction -{ - GENERATED_BODY() - - DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPassportGetAccessTokenOutputPin, FString, ErrorMessage, FString, AccessToken); - -public: - UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") - static UImtblPassportGetAccessTokenAsyncAction* GetAccessToken(UObject* WorldContextObject); - - virtual void Activate() override; - -private: - void DoGetAccessToken(TWeakObjectPtr JSGetConnector); - void OnGetAccessTokenResponse(FImmutablePassportResult Result); - - UPROPERTY(BlueprintAssignable) - FPassportGetAccessTokenOutputPin GotAccessToken; - UPROPERTY(BlueprintAssignable) - FPassportGetAccessTokenOutputPin Failed; -}; diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.h deleted file mode 100644 index 0fc19f23..00000000 --- a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetIdTokenAsyncAction.h +++ /dev/null @@ -1,34 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Immutable/ImmutablePassport.h" -#include "ImtblBlueprintAsyncAction.h" -#include "ImtblPassportGetIdTokenAsyncAction.generated.h" - -/** - * - */ -UCLASS() -class IMMUTABLE_API UImtblPassportGetIdTokenAsyncAction : public UImtblBlueprintAsyncAction -{ - GENERATED_BODY() - - DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPassportGetIdTokenOutputPin, FString, ErrorMessage, FString, IdToken); - -public: - UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") - static UImtblPassportGetIdTokenAsyncAction* GetIdToken(UObject* WorldContextObject); - - virtual void Activate() override; - -private: - void DoGetIdToken(TWeakObjectPtr JSGetConnector); - void OnGetIdTokenResponse(FImmutablePassportResult Result); - - UPROPERTY(BlueprintAssignable) - FPassportGetIdTokenOutputPin GotIdToken; - UPROPERTY(BlueprintAssignable) - FPassportGetIdTokenOutputPin Failed; -}; diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.h new file mode 100644 index 00000000..1af25899 --- /dev/null +++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetLinkedAddressesAsyncAction.h @@ -0,0 +1,33 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "ImtblBlueprintAsyncAction.h" + +#include "ImtblPassportGetLinkedAddressesAsyncAction.generated.h" + +/** + * The Blueprint node retrieves a list of wallet addresses linked to the passport wallet. + */ +UCLASS() +class IMMUTABLE_API UImtblPassportGetLinkedAddressesAsyncAction : public UImtblBlueprintAsyncAction +{ + GENERATED_BODY() + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPassportGetLinkedAddressesOutputPin, FString, ErrorMessage, const TArray &, Addresses); + +public: + UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") + static UImtblPassportGetLinkedAddressesAsyncAction* GetLinkedAddresses(UObject* WorldContextObject); + + virtual void Activate() override; + +private: + void DoGetLinkedAddresses(TWeakObjectPtr JSGetConnector); + void OnGetLinkedAddressesResponse(struct FImmutablePassportResult Result); + + UPROPERTY(BlueprintAssignable) + FPassportGetLinkedAddressesOutputPin Success; + UPROPERTY(BlueprintAssignable) + FPassportGetLinkedAddressesOutputPin Failed; +}; diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetTokenAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetTokenAsyncAction.h new file mode 100644 index 00000000..27a971b7 --- /dev/null +++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportGetTokenAsyncAction.h @@ -0,0 +1,46 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "ImtblBlueprintAsyncAction.h" + +#include "ImtblPassportGetTokenAsyncAction.generated.h" + + +/** + * Blueprint Node Utility to get tokens such as Id and Access tokens + */ +UCLASS() +class IMMUTABLE_API UImtblPassportGetTokenAsyncAction : public UImtblBlueprintAsyncAction +{ + GENERATED_BODY() + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPassportTokenOutputPin, FString, ErrorMessage, FString, Token); + +public: + UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") + static UImtblPassportGetTokenAsyncAction* GetAccessToken(UObject* WorldContextObject); + + UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") + static UImtblPassportGetTokenAsyncAction* GetIdToken(UObject* WorldContextObject); + + virtual void Activate() override; + +private: + enum TokenType + { + ID, + ACCESS, + NONE + }; + + void DoGetToken(TWeakObjectPtr JSGetConnector); + void OnGetTokenResponse(struct FImmutablePassportResult Result); + + UPROPERTY(BlueprintAssignable) + FPassportTokenOutputPin Success; + UPROPERTY(BlueprintAssignable) + FPassportTokenOutputPin Failed; + + TokenType Type = NONE; +}; diff --git a/Source/Immutable/Public/Immutable/ImmutableNames.h b/Source/Immutable/Public/Immutable/ImmutableNames.h index dbd3be62..8e87a6c6 100644 --- a/Source/Immutable/Public/Immutable/ImmutableNames.h +++ b/Source/Immutable/Public/Immutable/ImmutableNames.h @@ -27,6 +27,7 @@ namespace ImmutablePassportAction const FString GetEmail = TEXT("getEmail"); const FString GetAccessToken = TEXT("getAccessToken"); const FString GetIdToken = TEXT("getIdToken"); + const FString GetLinkedAddresses = TEXT("getLinkedAddresses"); const FString ImxTransfer = TEXT("imxTransfer"); const FString ImxBatchNftTransfer = TEXT("imxBatchNftTransfer"); const FString EnvSandbox = TEXT("sandbox"); diff --git a/Source/Immutable/Public/Immutable/ImmutablePassport.h b/Source/Immutable/Public/Immutable/ImmutablePassport.h index be8ee199..adde8fb4 100644 --- a/Source/Immutable/Public/Immutable/ImmutablePassport.h +++ b/Source/Immutable/Public/Immutable/ImmutablePassport.h @@ -120,6 +120,7 @@ class IMMUTABLE_API UImmutablePassport : public UObject void GetAccessToken(const FImtblPassportResponseDelegate& ResponseDelegate); void GetAddress(const FImtblPassportResponseDelegate& ResponseDelegate); void GetEmail(const FImtblPassportResponseDelegate& ResponseDelegate); + void GetLinkedAddresses(const FImtblPassportResponseDelegate& ResponseDelegate); /** * Create a new imx transfer request. @@ -164,6 +165,7 @@ class IMMUTABLE_API UImmutablePassport : public UObject static FString GetResponseResultAsString(const FImtblJSResponse& Response); static bool GetResponseResultAsBool(const FImtblJSResponse& Response); + static TArray GetResponseResultAsStringArray(const FImtblJSResponse& Response); #if PLATFORM_ANDROID void HandleDeepLink(FString DeepLink) const;