Create an MPC wallet
Overview
This guide describes how to implement MPC wallet creation in your game. After a successful integration, your players can create a wallet in-game and start sending transactions.
For information about MPC and MPC wallets, see About MPC technology.
Prerequisites
Make sure to ask the user to log in to your game using Sky Mavis account. Tis is a mandatory step to acquire the user's access token, which is necessary for every interaction with the MPC Solution.
Step 1. Collect a recovery password
The recovery password plays a crucial role in wallet recovery. It's used to encrypt and store the user's private key shard on our Sky Mavis backup servers.
If the user loses the recovery password, they lose access to their account. So make sure that your users choose strong passwords from the outset.
Before creating a wallet, prompt the user to set a strong recovery password that meets these criteria:
- Minimum 8 characters
- Includes at least one number
- Includes at least one special character
After the password is set, use it at the next step—wallet creation.
Step 2. Create an MPC wallet
To create an MPC wallet, you need the user's access token and recovery password. The wallet creation password includes the following steps:
- Generate
privateKeyShard
, which is the user's share of the MPC private key. - Encrypt
privateKeyShard
with the recovery password. - Push a copy of encrypted
privateKeyShard
to the Sky Mavis backup server. This copy is used in the recovery process when the player logs in with the wallet on a new device.
For uninterrupted wallet access across any device, remind your users of the crucial step: backing up their private key.
- Core
- Providers
- Unity
Create an MPC key:
const privateKeyShard = await mpcCore.generateMPCKey(accessToken : string);
Example:
const accessToken = `${ACCESS_TOKEN}`;
const privateKeyShard = await mpcCore.generateMPCKey(accessToken);
//...Encrypt the key and create its backup copy:
const backupKey = await mpcCore.createBackupKey(accessToken: string, privateKeyShard: string, password: string);
//...Example:
const accessToken = `${ACCESS_TOKEN}`;
const privateKeyShard = `${PRIVATE_KEY}`;
const password = `${RECOVERY_PASSWORD}`;
// Return backup key that is already encrypted
const backupKey = await mpcCore.createBackupKey(accessToken, privateKeyShard, password);
//..infoSky Mavis supports only
MPC_CMP_ECDSA_SECP256K1
, compatible with most EVM (Ethereum Virtual Machine) chains.
Here's a complete example:
// Import MpcCore
import { MpcCore} from "@axieinfinity/mpcjs";
// Initialize MpcCore
const mpcCore = MpcCore.init({
domain: "project-x.skymavis.one",
rpcURL: "https://saigon-testnet.roninchain.com/rpc",
secure: true,
})
// Create a handler to create a wallet
const handleCreateWallet = async () => {
try {
// Auth token
const token = `${ACCESS_TOKEN}`;
// Setup password
const password = `${RECOVERY_PASSWORD}`;
// Generate MPC key for new wallet
const response = await mpcCore.generateMPCKey(token)
// Back up key to server
const backupKey = await mpcCore.createBackupKey(token, response.data.key, password)
// Return encrypted key
console.log("Backup key ", backupKey)
} catch (error) {
console.error(error)
}
}
Create an MPC key:
const privateKeyShard = await mpcProviders.generateMPCKey(accessToken: string);
Example:
const accessToken = `${ACCESS_TOKEN}`;
const privateKeyShard = await mpcProviders.generateMPCKey(accessToken);
//...Encrypt the key and create its backup copy:
const backupKey = await mpcProviders.createBackupKey(accessToken: string, privateKeyShard: string, password: string);
//...Example:
const accessToken = `${ACCESS_TOKEN}`;
const privateKeyShard = `${PRIVATE_KEY}`;
const password = `${RECOVERY_PASSWORD}`;
// Return backup key that is already encrypted
const backupKey = await mpcProviders.createBackupKey(accessToken, privateKeyShard, password);
//..infoSky Mavis supports only
MPC_CMP_ECDSA_SECP256K1
, compatible with most EVM (Ethereum Virtual Machine) chains.
Here's a complete example:
// Import MpcProviders
import { MpcProviders } from "@axieinfinity/mpcjs";
// Init MpcProviders
const mpcProviders = MpcProviders.init(
{
domain: "project-x.skymavis.one",
rpcURL: "https://saigon-testnet.roninchain.com/rpc",
chainID: 2021,
secure: true,
}
)
// Create handler to create wallet
const handleCreateWallet = async () => {
try {
// Auth token
const token = `${ACCESS_TOKEN}`
// Setup password
const password = `${RECOVERY_PASSWORD}`
// Generate MPC key for new wallet
const response = await mpcProviders.generateMPCKey(token)
// Backup key to server
const backupKey = await mpcProviders.createBackupKey(token, response.data.key, password)
// Return encrypted key
console.log("Backup key ", backupKey)
} catch (error) {
console.error(error)
}
}
Create an MPC key:
Task<(bool success, MPCError error)> MPC.Keygen(string password);
Example:
string password = $"{RECOVERY_PASSWORD}";
var privateKeyShard = await MPC.Keygen(password);
if (privateKeyShard.error != null) {
Debug.LogError($"Error when generating MPC private key: {privateKeyShard.error.message}");
} else {
Debug.Log($"Result of MPC key generation: {privateKeyShard}");
}
The private key shard is used in the transaction signing process. We strongly recommend encrypting and storing a copy of the private key shard locally on your game client. Choose one of these secure options:
- Encrypt the shard with a user-defined PIN code.
- Encrypt the shard using the user's recovery password.
- Encrypt the shard with the user's fingerprint, facial recognition, or other device-specific biometrics.
Step 3. Retrieve wallet's public address
- Core
- Providers
- Unity
After the MPC wallet is generated, you can retrieve its public address as follows:
const address = await mpcCore.getCurrentUserProfile(accessToken)
Example:
const accessToken = `${ACCESS_TOKEN}`;
const address = await mpcCore.getCurrentUserProfile(accessToken);
console.log(profile.data.address)
After the MPC wallet is generated, you can retrieve its public address as follows:
const address = await mpcProviders.getCurrentUserProfile(accessToken)
Example:
const accessToken = `${ACCESS_TOKEN}`;
const address = await mpcProviders.getCurrentUserProfile(accessToken)
console.log(profile.data.address)
After the MPC wallet is generated, you can retrieve its public address as follows:
// Initialize the MPC environment
await MPC.Initialize(CreateAccessToken(userId), Environment.Production);
Debug.Log($"Wallet address: {MPC.WalletAddress}");
string address = MPC.WalletAddress;
Step 4. Verify wallet creation
To verify the wallet creation and user's ability to recover it, send an API request from your backend server to the Sky Mavis Account service to retrieve the updated user profile. The updated profile should contain the newly created Ronin Wallet.
The use of the Sky Mavis Account API requires an API key for authentication. For more information, see Get your API key.
GET https://api-gateway.skymavis.com/account/userinfo
X-API-Key: {YOUR_API_KEY}
Authorization: Bearer {ACCESS_TOKEN}
In the response, the ronin_address
field must match the wallet address you retrieve at the previous step, and the wallet_type
field must be equal to mpc
:
{
"ronin_address": "<string>",
"wallet_type": "mpc",
}