Build
Skip to content

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) {});
}