This guide walks you through creating a wallet, signing a message, and sending your first transaction using the MoonKey REST API.
Prerequisites
Before you begin, make sure you have:
- Completed the REST API setup guide
- Your MoonKey API key (test or live)
- A test user ID (or follow step 0 to create one)
All examples in this guide use test API keys. Replace sk_test_your_api_key_here with your actual API key.
Create a User (Optional)
If you want your wallet to be owned by a specific user, first create a user account:
curl -X POST "https://api.moonkey.fun/v1/auth/users/create" \
-H "Authorization: Bearer sk_test_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'
The response will include the user ID:
{
"id": "user_2Cu2uVhYy0OVgRcO913OsqIVaPI",
"app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
"email": "user@example.com",
"created_at": 1659638371,
"updated_at": 1659638371
}
Save the id field from the response. You’ll need it in the next step to create a wallet for this user.
1. Create a Wallet
Let’s create an Ethereum wallet for your user:
curl -X POST "https://api.moonkey.fun/v1/wallets/create" \
-H "Authorization: Bearer sk_test_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"wallet_type": "ethereum",
"user_id": "user_2Cu2uVhYy0OVgRcO913OsqIVaPI"
}'
The response will include the wallet ID and public address:
{
"id": "wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK",
"app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
"user_id": "user_2Cu2uVhYy0OVgRcO913OsqIVaPI",
"public_address": "0xf1347fd847f19c250b4c9678ecaa27b0f6ce8804",
"wallet_type": "ethereum",
"verified": true,
"is_default": true,
"is_read_only": false,
"is_imported": false,
"created_at": 1659638371,
"updated_at": 1659638371
}
If a wallet of the same type already exists for the user, MoonKey will return the existing wallet instead of creating a new one.
Save the wallet id and public_address. You’ll need these for the next steps.
2. Sign a Message
Now let’s sign a message with your newly created wallet:
curl -X POST "https://api.moonkey.fun/v1/wallets/wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK/sign_message" \
-H "Authorization: Bearer sk_test_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"message": "Hello from MoonKey!"
}'
The response will contain the signed message:
{
"wallet_id": "wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK",
"wallet": {
"id": "wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK",
"app_id": "app_25ldv51seNohTaYRsxdfoxMlAa2",
"user_id": "user_26l6ha8syVN8oqmaHaFShTxZ5RC",
"public_address": "0xb6acedc0cdcab7a4bb6c236976bb7df63bbcd567",
"wallet_type": "ethereum",
"verified": true,
"is_default": true,
"is_read_only": false,
"is_imported": false,
"created_at": 1647985945,
"updated_at": 1647985945
},
"signature": "0xc8723cfad978035ad3b960beade5237477aa91a9b01ba238d859e2a6e0fbded322e4732d3252afc4f7bec0018cc7bdddfe90547cc4fa985a400744315316198e01"
}
3. Send a Transaction
Finally, let’s send a transaction on Ethereum’s testnet, Sepolia:
curl -X POST "https://api.moonkey.fun/v1/wallets/wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK/sign_transaction" \
-H "Authorization: Bearer sk_test_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"eth_transaction": {
"to": "0xE9534C9fAF3cDBc636c25E1981A80EfaE03f187a",
"value": "0x38d7ea4c68000",
"nonce": "0x8",
"maxPriorityFeePerGas": "0x77359400",
"maxFeePerGas": "0xdf8475800",
"gas": "0x5208",
"chainId": "0xaa36a7"
}
}'
You’ll need to fund your wallet with Sepolia ETH for this step. Use a Sepolia faucet to send test ETH to your wallet’s public_address.
The response will contain the signature and signed transaction:
{
"wallet_id": "wallet_26l6hdwAXQr0y573AhQTXNDkyqK",
"wallet": {
"id": "wallet_26l6hdwAXQr0y573AhQTXNDkyqK",
"app_id": "app_25ldv51seNohTaYRsxdfoxMlAa2",
"user_id": "user_26l6ha8syVN8oqmaHaFShTxZ5RC",
"public_address": "0xb6acedc0cdcab7a4bb6c236976bb7df63bbcd567",
"wallet_type": "ethereum",
"verified": true,
"is_default": true,
"is_read_only": false,
"is_imported": false,
"created_at": 1647985945,
"updated_at": 1647985945
},
"signature": "0x744b61c44cdb250b89438709a9438a0b9e30c9c46e29776c93fb5e150e56021a",
"signed_transaction": "0xb87502f87205088477359400850df847580082520894e9534c9faf3cdbc636c25e1981a80efae03f187a87038d7ea4c6800080c001a0cd31b38c3e3a48230bee2d5c687a0b2a5efcb298c58cfc3b43449eefd17857cfa03f95b8bcad72f7bdca59025e797781f4ba3fde826f62b9d6997aaf19a7d7591b"
}
Broadcasting the Transaction
The signed_transaction is ready to be broadcast to the Ethereum network. You can use it with the eth_sendRawTransaction RPC method:
const signedTx = result.signed_transaction;
// Using a public RPC endpoint
const rpcResponse = await fetch('https://rpc.sepolia.org', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'eth_sendRawTransaction',
params: [signedTx],
id: 1
})
});
const txResult = await rpcResponse.json();
console.log('Transaction hash:', txResult.result);
Understanding Transaction Parameters
When sending a transaction, you need to provide several parameters:
| Parameter | Description | Example |
|---|
to | Recipient address | 0xE9534C9fAF3cDBc636c25E1981A80EfaE03f187a |
value | Amount in wei (hex) | 0x38d7ea4c68000 (0.001 ETH) |
nonce | Transaction count for the address | 0x8 |
maxPriorityFeePerGas | Priority fee (hex) | 0x77359400 |
maxFeePerGas | Max total fee (hex) | 0xdf8475800 |
gas | Gas limit (hex) | 0x5208 (21000 for simple transfer) |
chainId | Network chain ID (hex) | 0xaa36a7 (Sepolia) |
Use tools like eth-converter.com to convert between decimal and hex values for ETH amounts and gas prices.
Creating Solana Wallets
MoonKey also supports Solana wallets. To create a Solana wallet, simply change the wallet_type:
curl -X POST "https://api.moonkey.fun/v1/wallets/create" \
-H "Authorization: Bearer sk_test_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"wallet_type": "solana",
"user_id": "user_2Cu2uVhYy0OVgRcO913OsqIVaPI"
}'
Best Practices
Security
- Never expose API keys - Keep your secret API keys secure on your backend
- Use test keys for development - Test thoroughly before switching to live keys
- Validate user actions - Always verify that requests come from authenticated users
Transaction Safety
- Verify addresses - Always double-check recipient addresses before sending transactions
- Test on testnet first - Use Sepolia for Ethereum or Devnet for Solana before going to mainnet
- Monitor transaction status - Track transactions and handle failures gracefully
- Use appropriate gas limits - Ensure transactions have enough gas to complete
Error Handling
Always implement proper error handling for API requests:
try {
const response = await fetch('https://api.moonkey.fun/v1/wallets/create', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet_type: 'ethereum',
user_id: userId
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to create wallet');
}
const wallet = await response.json();
return wallet;
} catch (error) {
console.error('Wallet creation failed:', error.message);
// Handle error appropriately for your application
}
Troubleshooting
Common Issues
401 Unauthorized
- Verify your API key is correct
- Ensure you’re using the
Bearer token format
- Check that your API key hasn’t been revoked
404 Not Found
- Verify the wallet ID is correct
- Ensure the wallet belongs to your app
- Check that the user ID exists
Transaction Fails
- Verify the wallet has sufficient balance
- Check that gas limits and fees are appropriate
- Ensure the recipient address is valid
- Verify you’re on the correct network (testnet vs mainnet)
Rate Limiting
- Implement exponential backoff for retries
- Cache wallet data when possible
- Batch operations where appropriate
Support
Need help?