diff --git a/Content/BlueprintSampleContent/ImtblImxBatchNftTransferWidget.uasset b/Content/BlueprintSampleContent/ImtblImxBatchNftTransferWidget.uasset index b23bc64f..56cf2235 100644 Binary files a/Content/BlueprintSampleContent/ImtblImxBatchNftTransferWidget.uasset and b/Content/BlueprintSampleContent/ImtblImxBatchNftTransferWidget.uasset differ diff --git a/Content/BlueprintSampleContent/ImtblImxTransferWidget.uasset b/Content/BlueprintSampleContent/ImtblImxTransferWidget.uasset index ae18f6a4..bd0985d9 100644 Binary files a/Content/BlueprintSampleContent/ImtblImxTransferWidget.uasset and b/Content/BlueprintSampleContent/ImtblImxTransferWidget.uasset differ diff --git a/ImxBatchNftTransfer.png b/ImxBatchNftTransfer.png new file mode 100644 index 00000000..8d588db5 Binary files /dev/null and b/ImxBatchNftTransfer.png differ diff --git a/ImxTransferFlow.png b/ImxTransferFlow.png new file mode 100644 index 00000000..e5fdeb1c Binary files /dev/null and b/ImxTransferFlow.png differ diff --git a/README.md b/README.md index ae58fbc6..ddaba16e 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,19 @@ Once the gamer is connected to Passport, the SDK will store your credentials (ac See this Blueprint showing how to logout from passport ![Passport Logout Blueprint](PassportLogoutFlow.jpg) +#### Imx Transfer + +> Note: The transfers feature require pre-approval from Immutable. Please [contact us](https://docs.immutable.com/docs/x/contact/) before making use of it. + +To transfer tokens of type ETH, ERC20 or ERC721 use UImmutablePassport::ImxTransfer method. See this Blueprint example showing how to use Imx Transfer + +![Imx Transfer](ImxTransferFlow.png) + +To transfer multiple NFTs in a single transaction use UImmutablePassport::ImxBatchNftTransfer method. See this Blueprint example showing how to use Imx Batch Nft Transfer + +![Imx Batch Nft Transfer](ImxBatchNftTransfer.png) + + ### Android and iOS PKCE login (Unreal Engine 5.0+ only) For Android and iOS, you can use the [Authorization Code Flow with Proof Key for Code Exchange (PKCE)](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-proof-key-for-code-exchange-pkce) login flow instead of [Device Code Authorisation](https://auth0.com/docs/get-started/authentication-and-authorization-flow/device-authorization-flow#:~:text=Your%20Auth0%20Authorization%20Server%20redirects,authorized%20to%20access%20the%20API.). This means the gamer has one less step to complete and will be redirected back to the game after successfully authenticating. @@ -108,7 +121,7 @@ To use this flow you will need to: #### Unreal Editor Android setup -1. In Unreal Editor go to **Project Settings** -> **Android** -> **Advanced APK Packaging** +1. In Unreal Editor go to **Project Settings** -> **Android** -> **Advanced APK Packaging** 2. Add the following code inside the **Extra Settings for \ section (\n to separate lines)** field: ```XML @@ -119,7 +132,7 @@ The application will now open when the device processes any link that starts wit #### Unreal Editor iOS setup -1. In Unreal Editor go to **Project Settings** -> **iOS** -> **Extra PList Data** +1. In Unreal Editor go to **Project Settings** -> **iOS** -> **Extra PList Data** 2. Add the following code inside the **Additional Plist Data** field: ``` @@ -135,12 +148,15 @@ See the [sample game](https://github.com/immutable/sample-unreal-game) for an ex | Method | Description | |--- |:---| -| GetAddress | Gets Wallet Address | -| GetEmail | Get Email Address associated with the Wallet Address | -| CheckStoredCredentials | Checks if there are stored credits from previous login | | Connect | Log into Passport using [Device Code Authorisation](https://auth0.com/docs/get-started/authentication-and-authorization-flow/device-authorization-flow#:~:text=Your%20Auth0%20Authorization%20Server%20redirects,authorized%20to%20access%20the%20API.) | | ConnectSilent | Attempts to login using stored credentials | | ConnectPKCE | (Android and iOS on Unreal Engine 5.0+ only) Log into Passport using [Authorization Code Flow with Proof Key for Code Exchange (PKCE)](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-proof-key-for-code-exchange-pkce) | +| CheckStoredCredentials | Checks if there are stored credits from previous login | +| GetAddress | Gets Wallet Address | +| GetEmail | Get Email Address associated with the Wallet Address | +| ImxTransfer | ImxTransfer used to send tokens of type ETH, ERC20, ERC721 to reciever's address| +| ImxBatchNftTransfer | ImxBatchNftTransfer used to send multiple Nft tokens in a single transaction to reciever's address| + See the [ImmutablePassport.h](https://github.com/immutable/unreal-immutable-sdk/blob/dc39324db204f2ba30e9c9f0ca25c070987785cb/Source/Immutable/Public/Immutable/ImmutablePassport.h#L115C8-L115C8) header for the full API. diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.cpp index 3a081a62..9a0c2283 100644 --- a/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.cpp +++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.cpp @@ -8,7 +8,7 @@ #include "Immutable/Misc/ImtblLogging.h" -UImmutablePassportImxBatchNftTransferAsyncAction* UImmutablePassportImxBatchNftTransferAsyncAction::BatchNftTransfer(UObject* WorldContextObject, +UImmutablePassportImxBatchNftTransferAsyncAction* UImmutablePassportImxBatchNftTransferAsyncAction::ImxBatchNftTransfer(UObject* WorldContextObject, const TArray& NftTransferDetails) { UImmutablePassportImxBatchNftTransferAsyncAction* BlueprintNode = NewObject(); @@ -40,7 +40,7 @@ void UImmutablePassportImxBatchNftTransferAsyncAction::DoTransfer(TWeakObjectPtr Request.nftTransferDetails = NftTransferDetails; // Run Transfer - GetSubsystem()->GetPassport()->BatchNftTransfer(Request, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImmutablePassportImxBatchNftTransferAsyncAction::OnTransferResponse)); + GetSubsystem()->GetPassport()->ImxBatchNftTransfer(Request, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImmutablePassportImxBatchNftTransferAsyncAction::OnTransferResponse)); } diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxTransferAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxTransferAsyncAction.cpp index d31a6969..44ca712a 100644 --- a/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxTransferAsyncAction.cpp +++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportImxTransferAsyncAction.cpp @@ -8,7 +8,7 @@ #include "Immutable/Misc/ImtblLogging.h" -UImmutablePassportImxTransferAsyncAction* UImmutablePassportImxTransferAsyncAction::Transfer(UObject* WorldContextObject, +UImmutablePassportImxTransferAsyncAction* UImmutablePassportImxTransferAsyncAction::ImxTransfer(UObject* WorldContextObject, const FString& Receiver, const FString& Type, const FString& Amount, const FString& TokenId, const FString& TokenAddress) { @@ -47,7 +47,7 @@ void UImmutablePassportImxTransferAsyncAction::DoTransfer(TWeakObjectPtrGetPassport()->Transfer(Request, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImmutablePassportImxTransferAsyncAction::OnTransferResponse)); + GetSubsystem()->GetPassport()->ImxTransfer(Request, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImmutablePassportImxTransferAsyncAction::OnTransferResponse)); } diff --git a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp index edf8c580..5397ea5b 100644 --- a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp +++ b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp @@ -310,21 +310,21 @@ void UImmutablePassport::GetEmail(const FImtblPassportResponseDelegate& Response ); } -void UImmutablePassport::Transfer(const FImxTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate) +void UImmutablePassport::ImxTransfer(const FImxTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate) { IMTBL_LOG("Tranfer Request: %s", *UStructToJsonString(RequestData)) CallJS( - ImmutablePassportAction::Transfer, + ImmutablePassportAction::ImxTransfer, UStructToJsonString(RequestData), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnTransferResponse) ); } -void UImmutablePassport::BatchNftTransfer(const FImxBatchNftTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate) +void UImmutablePassport::ImxBatchNftTransfer(const FImxBatchNftTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate) { CallJS( - ImmutablePassportAction::BatchNftTransfer, + ImmutablePassportAction::ImxBatchNftTransfer, RequestData.ToJsonString(), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnBatchNftTransferResponse) @@ -772,7 +772,7 @@ void UImmutablePassport::OnTransferResponse(FImtblJSResponse Response) bool bSuccess = true; if (!Response.success) { - IMTBL_LOG("Transfer failed."); + IMTBL_LOG("ImxTransfer failed."); if (Response.Error.IsSet()) { Msg = Response.Error->ToString(); @@ -798,7 +798,7 @@ void UImmutablePassport::OnBatchNftTransferResponse(FImtblJSResponse Response) bool bSuccess = true; if (!Response.success || !Response.JsonObject->HasTypedField(TEXT("result"))) { - IMTBL_LOG("Transfer failed."); + IMTBL_LOG("ImxBatchNftTransfer failed."); if (Response.Error.IsSet()) { Msg = Response.Error->ToString(); diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.h index ba450da9..a4928108 100644 --- a/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.h +++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxBatchNftTransferAsyncAction.h @@ -19,7 +19,7 @@ class IMMUTABLE_API UImmutablePassportImxBatchNftTransferAsyncAction : public UI public: UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") - static UImmutablePassportImxBatchNftTransferAsyncAction* BatchNftTransfer(UObject* WorldContextObject, + static UImmutablePassportImxBatchNftTransferAsyncAction* ImxBatchNftTransfer(UObject* WorldContextObject, const TArray& NftTransferDetails); virtual void Activate() override; diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxTransferAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxTransferAsyncAction.h index 576c4023..82f03fda 100644 --- a/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxTransferAsyncAction.h +++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportImxTransferAsyncAction.h @@ -19,7 +19,7 @@ class IMMUTABLE_API UImmutablePassportImxTransferAsyncAction : public UImtblBlue public: UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") - static UImmutablePassportImxTransferAsyncAction* Transfer(UObject* WorldContextObject, + static UImmutablePassportImxTransferAsyncAction* ImxTransfer(UObject* WorldContextObject, const FString& Receiver, const FString& Type, const FString& Amount, const FString& TokenId, const FString& TokenAddress); diff --git a/Source/Immutable/Public/Immutable/ImmutablePassport.h b/Source/Immutable/Public/Immutable/ImmutablePassport.h index 2b28b7be..4c2cf67b 100644 --- a/Source/Immutable/Public/Immutable/ImmutablePassport.h +++ b/Source/Immutable/Public/Immutable/ImmutablePassport.h @@ -29,8 +29,8 @@ namespace ImmutablePassportAction #endif const FString GetAddress = TEXT("getAddress"); const FString GetEmail = TEXT("getEmail"); - const FString Transfer = TEXT("imxTransfer"); - const FString BatchNftTransfer = TEXT("imxBatchNftTransfer"); + const FString ImxTransfer = TEXT("imxTransfer"); + const FString ImxBatchNftTransfer = TEXT("imxBatchNftTransfer"); const FString EnvSandbox = TEXT("sandbox"); const FString EnvProduction = TEXT("production"); } @@ -461,18 +461,18 @@ class IMMUTABLE_API UImmutablePassport : public UObject void GetEmail(const FImtblPassportResponseDelegate& ResponseDelegate); /** - * Create a new transfer request. + * Create a new imx transfer request. * @param RequestData The transfer details structure of type FImxTransferRequest * @param ResponseDelegate The response delegate of type FImtblPassportResponseDelegate to call on response from JS. */ - void Transfer(const FImxTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate); + void ImxTransfer(const FImxTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate); /** - * Creates a new batch nft transfer request with the given transfer details. + * Creates a new imx batch nft transfer request with the given transfer details. * @param RequestData The transfer details structure of type FImxBatchNftTransferRequest * @param ResponseDelegate The response delegate of type FImtblPassportResponseDelegate to call on response from JS. */ - void BatchNftTransfer(const FImxBatchNftTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate); + void ImxBatchNftTransfer(const FImxBatchNftTransferRequest& RequestData, const FImtblPassportResponseDelegate& ResponseDelegate); protected: void Setup(TWeakObjectPtr Connector);