Wallet
Unreal Wallet
Wallet creation, address lookup, signing, sending, and receipt waiting.
Prerequisites
- Signed in with
SignIn(...)orSignInWithCreateAsync(...) - EVM chain routing requires a
ChainId(recommended:eip155:<number>) - Confirmation UI enabled via
EnableSignConfirmation(AppName)
Address and wallet APIs
// Setup wallet with UI (PIN and wallet found modals handled internally)
Sdk->SetupWalletWithUIAsync(Sub,
FCROSSxCreateWalletDelegate::CreateLambda([](const FCROSSxCreateWalletResult& R)
{
UE_LOG(LogTemp, Log, TEXT("Wallet: %s"), *R.Address);
})
);
// Create wallet with migration control
Sdk->CreateWalletWithMigrateAsync(true,
FCROSSxCreateWalletDelegate::CreateLambda([](const FCROSSxCreateWalletResult& R) { /* ... */ })
);
// Synchronous address APIs
FCROSSxGetAddressResponse Primary = Sdk->GetAddress();
FCROSSxGetAddressResponse ByIndex = Sdk->GetAddress(0);
FCROSSxGetAddressesResponse All = Sdk->GetAddresses();
// Check wallet state
Sdk->CheckWalletAsync(
FCROSSxCheckWalletDelegate::CreateLambda([](const FCROSSxCheckWalletResponse& R) { /* ... */ })
);
// Wallet selection with UI
Sdk->SelectWalletWithUIAsync(TEXT(""),
FCROSSxWalletSelectionDelegate::CreateLambda([](const FCROSSxWalletSelectionResult& R) { /* ... */ })
);Wallet password and biometrics
The SDK may show password entry and confirmation UI before signing and sending. After verification once, the password is reused for later operations.
bool bCan = Sdk->CanUseBiometric();
bool bEnabled = Sdk->IsBiometricEnabled();
Sdk->SetBiometricEnabled(true);Message and typed data signing
Confirmation UI is shown automatically for UI Flow APIs.
FString ChainId = TEXT("eip155:612044");
// Sign message with UI
Sdk->SignMessageWithUIAsync(TEXT("Hello CROSSx"), ChainId, From,
FCROSSxSignMessageDelegate::CreateLambda([](const FCROSSxSignMessageResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("Signature: %s"), *R.Signature);
})
);
// Sign typed data with UI
Sdk->SignTypedDataWithUIAsync(From, TypedDataJson, ChainId,
FCROSSxSignTypedDataDelegate::CreateLambda([](const FCROSSxSignTypedDataResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("Signature: %s"), *R.Signature);
})
);
// Off-chain typed data (no chainId required)
Sdk->SignTypedDataOffchainWithUIAsync(From, TypedDataJson,
FCROSSxSignTypedDataDelegate::CreateLambda([](const FCROSSxSignTypedDataResponse& R) { /* ... */ })
);Transaction signing
FCROSSxUnsignedTx Tx;
Tx.ChainId = TEXT("eip155:612044");
Tx.From = TEXT("0xYourAddress");
Tx.To = TEXT("0xRecipient");
Tx.Value = TEXT("0xde0b6b3a7640000");
Tx.Data = TEXT("0x");
// Sign transaction with UI
Sdk->SignTransactionWithUIAsync(Tx, Tx.ChainId,
FCROSSxSignTxDelegate::CreateLambda([](const FCROSSxSignTxResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("SignedTx: %s"), *R.SignedTx);
})
);You can also use FCROSSxWalletUnsignedTransaction for SDK-level models:
FCROSSxWalletUnsignedTransaction WalletTx;
WalletTx.ChainId = TEXT("eip155:612044");
WalletTx.From = TEXT("0xYourAddress");
WalletTx.To = TEXT("0xRecipient");
WalletTx.Value = TEXT("0xde0b6b3a7640000");
WalletTx.Data = TEXT("0x");
FCROSSxUnsignedTx RawTx = WalletTx.ToUnsignedTx();Sending transactions
// Send with UI
Sdk->SendTransactionWithUIAsync(Tx, Tx.ChainId,
FCROSSxSendTxDelegate::CreateLambda([](const FCROSSxSendTxResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("TxHash: %s"), *R.TxHash);
})
);Send and wait for receipt with UI
Sdk->SendTransactionWithWaitForReceiptWithUIAsync(Tx, Tx.ChainId,
FCROSSxTxReceiptDelegate::CreateLambda([](const FCROSSxTxReceiptResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("TxHash: %s, Status: %s"), *R.TransactionHash, *R.Status);
}),
TEXT(""), TEXT(""), TEXT(""),
30000, 1000
);Manual receipt polling
// Synchronous
FCROSSxTxReceiptResponse Receipt = Sdk->WaitForTxReceipt(
TEXT("0x..."), TEXT("eip155:612044"), 30000, 1000
);
// Asynchronous
Sdk->WaitForTxReceiptAsync(TEXT("0x..."), TEXT("eip155:612044"), 30000, 1000,
FCROSSxTxReceiptDelegate::CreateLambda([](const FCROSSxTxReceiptResponse& R)
{
UE_LOG(LogTemp, Log, TEXT("Status: %s"), *R.Status);
})
);RPC helpers
// JSON-RPC
FCROSSxJsonRpcRequest RpcReq;
RpcReq.Method = TEXT("eth_call");
RpcReq.Params = TEXT("[]");
FCROSSxJsonRpcResponse RpcResp = Sdk->WalletRpc(RpcReq, TEXT("eip155:612044"));
// Balance and nonce
FString Balance = Sdk->GetBalance(TEXT("0xYourAddress"), TEXT("eip155:612044"));
FString Nonce = Sdk->GetNonce(TEXT("0xYourAddress"), TEXT("eip155:612044"), TEXT("pending"));
WalletRpcis intended for contract read/call only (e.g.eth_call). Sending/signing transaction methods are not supported through this RPC API.
Confirmation UI
The SDK provides built-in Slate modals for transaction confirmation. Enable them after initialization:
Sdk->EnableSignConfirmation(TEXT("My Game"), ECROSSxThemeMode::Dark);Modal types managed by the SDK:
- SignConfirmationModal — sign/send confirmation
- WalletFoundModal — existing wallet recovery prompt (managed internally)
- PinInputModal — password entry (managed internally)
- SessionExpiredModal — session expiry handling
- WalletCompleteModal — wallet creation success notification
- TransactionCompleteModal — transaction completion status
Updated about 20 hours ago