How to build a Game with Unreal Engine
In this guide we will walk you through how to integrate Embedded Wallet features using Sequence's Unreal SDK. Checkout the Boilerplate for this guide.
Learn more about Embedded Wallets.
1. Setup
Installation
To get started, download the latest version
of the Sequence SDK and put the SequencePlugin
folder into your Unreal project's Plugin
folder.
Alternatively, learn how to get the SDK from the Epic Games Marketplace.
Configure your Project
Now create the SequenceConfig.ini
file, based on this format, in your project's Config/
directory and include the
WaaS- and Project Key from the Sequence Builder. Generate a 32-character encryption key. This key will be used to securely store your user credentials.
The remaining values can be filled in later or whenever new authentication options are needed.
Include the Built-In UI
Let's build on top of the Pawn BP_CustomSpectatorPawn
and GameMode GM_Sequence
included with the SDK by duplicating them into our project.
This will allow us to customize them as needed.
We recommend using the Built-In UI for development purposes, learn how to create your own UI.
2. Interact with the SDK
To enable interaction with the Sequence SDK, start by creating a widget blueprint for your project.
Open the Sequence Pawn, locate the Auth Success event, and create a UserWidget of your choice.
Finally, implement the widget functionality using C++ or use the Blueprint components directly.
For Blueprints, use the SequenceWalletBP
reference to access the functions in the following sections.
3. Display Wallet Information
To display the wallet's address and balance, first retrieve the user's wallet reference. Then, use it to fetch and display the wallet's address and current balance directly from the connected blockchain.
Example Use Case:
Build a UserWidget for your users Web3 profile.
void GameUserWidget::UpdateAddress()
{
// Get the reference to the users wallet
const TOptional<USequenceWallet*> WalletOptional = USequenceWallet::Get();
const USequenceWallet* Wallet = WalletOptional.GetValue();
// Apply the wallet address to a text field
const FString Address = Wallet->GetWalletAddress();
this->WalletAddress->SetText(FText::FromString("Wallet Address: " + Address));
}
void GameUserWidget::UpdateBalance()
{
// Get the reference to the users wallet
const TOptional<USequenceWallet*> WalletOptional = USequenceWallet::Get();
const USequenceWallet* Wallet = WalletOptional.GetValue();
const FString Address = Wallet->GetWalletAddress();
// Make an asynchronous request to fetch the users balance for the chains native token
Wallet->GetEtherBalance(Address, [this](const FSeqEtherBalance& Balance)
{
const FString BalanceText = FString::Printf(TEXT("Balance: %lld"), Balance.balanceWei);
this->EtherBalance->SetText(FText::FromString(BalanceText));
},
[](const FSequenceError& Error){});
}
4. Sign a Message
To sign a message, first retrieve the user's wallet reference. Then, use the input message from the boilerplate and initiate the signing process through the wallet to generate the signature.
Example Use Case:
You can use this feature to sign a message from your backend, allowing you to verify your user's wallet upon receipt.
void GameUserWidget::SignMessage()
{
// Get the user input from the UEditableTextBox
const FString& MessageInputText = this->MessageInput->GetText().ToString();
const TOptional<USequenceWallet*> WalletOptional = USequenceWallet::Get();
const USequenceWallet* Wallet = WalletOptional.GetValue();
// Sign the user's input message
Wallet->SignMessage(MessageInputText, [this, MessageInputText](const FSeqSignMessageResponse_Response& Response)
{
const FString& SignedMessageText = *Response.Data.Message;
this->SignedMessage->SetText(FText::FromString("Signed Message: " + SignedMessageText));
},
[](const FSequenceError& Error){});
}
5. Send an ERC20 Transaction
To send an ERC20 transaction, first retrieve the user's wallet reference. Then, use the recipient's address, token contract address, and amount from the boilerplate's input fields to initiate the transaction.
Example Use Case:
A user initiates a payment transaction to another user within your game client.
void GameUserWidget::SendERC20Transaction()
{
// Get the reference to the sequence wallet.
const TOptional<USequenceWallet*> WalletOptional = USequenceWallet::Get();
const USequenceWallet* Wallet = WalletOptional.GetValue();
// Here we get the transaction values from the widgets input fields.
const FString RecipientAddress = RecipientAddressInput->GetText().ToString();
const FString TokenContractAddress = TokenContractAddressInput->GetText().ToString();
const FString TransactionValue = TransactionValueInput->GetText().ToString();
// Create the transaction object.
TArray<TUnion<FRawTransaction, FERC20Transaction, FERC721Transaction, FERC1155Transaction, FDelayedTransaction>> Txn;
FERC20Transaction T20;
T20.to = ToAddress;
T20.tokenAddress = TokenAddress;
T20.value = TransactionValue;
Txn.Push(TUnion<FRawTransaction, FERC20Transaction, FERC721Transaction, FERC1155Transaction, FDelayedTransaction>(T20));
// Get the fee options before we send the transaction,
Wallet->GetFeeOptions(Txn, [this, Txn, Wallet](const TArray<FFeeOption>& Response)
{
const FFeeOption SelectedFeeOption = Response[0];
UE_LOG(LogTemp, Log, TEXT("Using FeeOption value: %s"), *SelectedFeeOption.Value);
// Send the transaction including the selected fee option.
Wallet->SendTransactionWithFeeOption(Txn, SelectedFeeOption, [=](const FSeqTransactionResponse_Data& Transaction)
{
UE_LOG(LogTemp, Log, TEXT("SUCCESS: Transaction sent, hash: %s"), *Transaction.TxHash);
},
[](const FSequenceError& Error) {});
},
[](const FSequenceError& Error) {});
}