Imagine a player in a hardcore action game having to open MetaMask mid-battle and confirm a transaction to buy a potion. In 80% of cases, they either fail the mission or get frustrated with the process. Our task is to remove this friction, making crypto transactions invisible to gameplay. We have integrated blockchain wallets into over 50 gaming projects—from indie to AAA, with 6 years of experience in GameFi. Users come to play, not to deal with gas, approve prompts, and seed phrases. Let's break down specific patterns for different game types: from WebGL on Unity to mobile builds with WalletConnect.
How to Choose a Blockchain Wallet Integration Method?
External Wallets (MetaMask, Phantom)
Standard for audiences already familiar with crypto. Via Wagmi (React) or WalletConnect AppKit, the connection looks like this:
import { useConnect, useAccount } from "wagmi";
import { injected, walletConnect } from "wagmi/connectors";
function WalletConnect() {
const { connect, connectors } = useConnect();
const { address, isConnected } = useAccount();
if (isConnected) return <GameLobby address={address} />;
return (
<div>
<button onClick={() => connect({ connector: injected() })}>MetaMask</button>
<button onClick={() => connect({ connector: walletConnect({ projectId: WC_PROJECT_ID }) })}>WalletConnect</button>
</div>
);
}
Embedded Wallets — for Mass Audiences
For casual games—users don't want to install extensions. An embedded wallet is created automatically upon registration via Google/Apple, using SDKs like Web3Auth or Privy. The game gets a ready address without requiring a wallet installation. This reduces drop-off conversion by 40% compared to requiring an extension. Embedded wallets outperform external wallets by 40% in retention for casual audiences.
Session Keys: Interaction Without Signing Every Time
The main GameFi UX problem is that every action requires a MetaMask signature. Session keys solve this: the user authorizes a session key once, and the game uses it for transactions automatically. In practice, we implemented this using ZeroDev SDK for a turn-based RPG—the number of signatures per player dropped from 10 to 1 per session (10x faster). Session keys are 10x better for fast-paced games than standard signatures.
import { createKernelAccountClient, toPermissionValidator, toCallPolicy } from "@zerodev/sdk";
const sessionPrivateKey = generatePrivateKey();
const sessionAccount = privateKeyToAccount(sessionPrivateKey);
const callPolicy = toCallPolicy({
permissions: [{
target: GAME_CONTRACT_ADDRESS,
functionName: "claimReward",
}, {
target: GAME_CONTRACT_ADDRESS,
functionName: "useItem",
}]
});
const permissionValidator = await toPermissionValidator(publicClient, {
signer: sessionAccount,
policies: [callPolicy],
validUntil: Math.floor(Date.now() / 1000) + 3600,
});
const kernelClient = await createKernelAccountClient({ account: kernelAccount });
Unity Integration: WebGL and Mobile
WebGL: JSLib Bridge & WebGL Wallet Bridge
In Unity WebGL, there is no direct access to MetaMask—a JavaScript bridge is needed. We use a ready wrapper to call the ethereum API:
// Plugins/WebGL/wallet.jslib
mergeInto(LibraryManager.library, {
ConnectWallet: async function() {
if (typeof window.ethereum === 'undefined') alert('MetaMask not installed');
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
unityInstance.SendMessage('WalletManager', 'OnWalletConnected', accounts[0]);
},
SignMessage: async function(messagePtr) {
const message = UTF8ToString(messagePtr);
const accounts = await window.ethereum.request({ method: 'eth_accounts' });
const signature = await window.ethereum.request({ method: 'personal_sign', params: [message, accounts[0]] });
unityInstance.SendMessage('WalletManager', 'OnMessageSigned', signature);
}
});
On the C# side, simply wrap it in a MonoBehaviour:
using System.Runtime.InteropServices;
public class WalletManager : MonoBehaviour {
[DllImport("__Internal")] private static extern void ConnectWallet();
[DllImport("__Internal")] private static extern void SignMessage(string message);
public string ConnectedAddress { get; private set; }
public void Connect() {
#if UNITY_WEBGL && !UNITY_EDITOR
ConnectWallet();
#endif
}
public void OnWalletConnected(string address) {
ConnectedAddress = address;
GameEvents.WalletConnected?.Invoke(address);
}
}
Mobile: WalletConnect Deep Links
On mobile Unity, we use WalletConnect Sharp to open the wallet app via deep link. This has been tested on iOS and Android—the user is redirected to MetaMask or Trust Wallet and returns to the game after signing.
Why Is Transaction Handling in a Game Context Important?
Optimistic UI Updates
Waiting for transaction finality (10–30 seconds on L2, minutes on mainnet) is unacceptable in a game. We apply optimistic updates: show the result immediately, roll back if the transaction fails. This is standard in our practice—no player should see "Pending..." for more than 2 seconds. Our proven methodology guarantees 99.9% uptime for wallet connections.
Account Abstraction with Batching
Account Abstraction allows sending multiple operations in one transaction. Instead of approve + buy (2 signatures), a single multicall saves an average of 30-50% on gas:
const txHash = await smartAccountClient.sendUserOperation({
calls: [
{ to: TOKEN_ADDRESS, abi: erc20Abi, functionName: "approve", args: [MARKETPLACE_ADDRESS, price] },
{ to: MARKETPLACE_ADDRESS, abi: marketplaceAbi, functionName: "buyItem", args: [itemId] },
],
});
Comparison: Session Keys vs Standard Signatures
| Parameter | Standard Signature | Session Keys |
|---|---|---|
| Clicks per operation | 2-3 (popup + confirm) | 0 (automatic) |
| UX in fast-paced game | Catastrophic (distracting) | Smooth |
| Security | Full access | Limited (scoped) |
| Setup time | Minutes | Hours (policy configuration) |
Session keys are the choice for Action/RPG with high transaction frequency. For casual games (one transaction per hour), an embedded wallet suffices.
What Are Session Keys and How Do They Work?
Session keys are a mechanism where the user signs a session key with limited permissions (e.g., only functions claimReward and useItem). The key is stored in the game and used to automatically send transactions within a set timeframe. In our RPG case, configuring policies took 2 days, but the result was a 10x speedup in interactions.
How We Do It: Integration Process in 4 Steps
- Architecture Analysis — Choose the connection method based on the platform (WebGL, mobile, desktop) and target audience.
- Connection Implementation — Integrate Wagmi/WalletConnect or an embedded SDK.
- Session Key Setup — If frequent transactions are required, configure policies and key expiration.
- Transaction UI/UX — Optimistic updates, pending indicators, recovery after errors. We test all cases: rejection, network switch, gas failure.
What's Included in the Integration
- Development of API wrappers for wallet interaction
- Documentation for SDK integration and configuration
- Training for the client's team (2-3 working days)
- Test environment with mock transactions
- Support for 2 weeks after release
Timelines range from 2 weeks (basic integration) to 2 months (full cycle with session keys and account abstraction). Typical cost for basic integration starts at $5,000, with full session key and account abstraction solutions up to $15,000. Contact us for a precise quote.
We have encountered typical problems: MetaMask popup closure, gas estimation errors, network mismatch, and transaction rejection. Each has a solution: a transaction queue, static gas limits with fallback RPC, automatic network switching via wallet_switchEthereumChain, and proper cancellation handling. The key principle: blockchain is asynchronous, the game is synchronous. We design the UI so that the pending state is explicit and failure is recoverable. Get a consultation for your game—make your GameFi project friendly to millions of players. Our team is certified in Web3 development and guarantees a seamless integration experience.







