> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streambird.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

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](/get-started/rest-api/setup)
* Your MoonKey API key (test or live)
* A test user ID (or follow step 0 to create one)

<Info>
  All examples in this guide use test API keys. Replace `sk_test_your_api_key_here` with your actual API key.
</Info>

## Create a User (Optional)

If you want your wallet to be owned by a specific user, first create a user account:

<CodeGroup>
  ```bash cURL theme={null}
  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"
    }'
  ```

  ```javascript JavaScript theme={null}
  const apiKey = process.env.MOONKEY_SECRET_KEY;

  const response = await fetch('https://api.moonkey.fun/v1/auth/users/create', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      email: 'user@example.com'
    })
  });

  const user = await response.json();
  console.log('User created:', user.id);
  ```

  ```python Python theme={null}
  import requests
  import os

  api_key = os.environ.get('MOONKEY_SECRET_KEY')

  url = "https://api.moonkey.fun/v1/auth/users/create"
  headers = {
      "Authorization": f"Bearer {api_key}",
      "Content-Type": "application/json"
  }
  payload = {
      "email": "user@example.com"
  }

  response = requests.post(url, json=payload, headers=headers)
  user = response.json()
  print(f"User created: {user['id']}")
  ```
</CodeGroup>

The response will include the user ID:

```json theme={null}
{
  "id": "user_2Cu2uVhYy0OVgRcO913OsqIVaPI",
  "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
  "email": "user@example.com",
  "created_at": 1659638371,
  "updated_at": 1659638371
}
```

<Tip>
  Save the `id` field from the response. You'll need it in the next step to create a wallet for this user.
</Tip>

## 1. Create a Wallet

Let's create an Ethereum wallet for your user:

<CodeGroup>
  ```bash cURL theme={null}
  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"
    }'
  ```

  ```javascript JavaScript theme={null}
  const apiKey = process.env.MOONKEY_SECRET_KEY;
  const userId = 'user_2Cu2uVhYy0OVgRcO913OsqIVaPI';

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

  const wallet = await response.json();
  console.log('Wallet created:', wallet.public_address);
  ```

  ```python Python theme={null}
  import requests
  import os

  api_key = os.environ.get('MOONKEY_SECRET_KEY')
  user_id = 'user_2Cu2uVhYy0OVgRcO913OsqIVaPI'

  url = "https://api.moonkey.fun/v1/wallets/create"
  headers = {
      "Authorization": f"Bearer {api_key}",
      "Content-Type": "application/json"
  }
  payload = {
      "wallet_type": "ethereum",
      "user_id": user_id
  }

  response = requests.post(url, json=payload, headers=headers)
  wallet = response.json()
  print(f"Wallet created: {wallet['public_address']}")
  ```
</CodeGroup>

The response will include the wallet ID and public address:

```json theme={null}
{
  "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
}
```

<Note>
  If a wallet of the same type already exists for the user, MoonKey will return the existing wallet instead of creating a new one.
</Note>

<Tip>
  Save the wallet `id` and `public_address`. You'll need these for the next steps.
</Tip>

## 2. Sign a Message

Now let's sign a message with your newly created wallet:

<CodeGroup>
  ```bash cURL theme={null}
  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!"
    }'
  ```

  ```javascript JavaScript theme={null}
  const apiKey = process.env.MOONKEY_SECRET_KEY;
  const walletId = 'wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK';

  const response = await fetch(
    `https://api.moonkey.fun/v1/wallets/${walletId}/sign_message`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        message: 'Hello from MoonKey!'
      })
    }
  );

  const result = await response.json();
  console.log('Message signed:', result.signature);
  ```

  ```python Python theme={null}
  import requests
  import os

  api_key = os.environ.get('MOONKEY_SECRET_KEY')
  wallet_id = 'wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK'

  url = f"https://api.moonkey.fun/v1/wallets/{wallet_id}/sign_message"
  headers = {
      "Authorization": f"Bearer {api_key}",
      "Content-Type": "application/json"
  }
  payload = {
      "message": "Hello from MoonKey!"
  }

  response = requests.post(url, json=payload, headers=headers)
  result = response.json()
  print(f"Message signed: {result['signature']}")
  ```
</CodeGroup>

The response will contain the signed message:

```json theme={null}
{
  "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](https://sepolia.etherscan.io/):

<CodeGroup>
  ```bash cURL theme={null}
  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"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const apiKey = process.env.MOONKEY_SECRET_KEY;
  const walletId = 'wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK';

  const response = await fetch(
    `https://api.moonkey.fun/v1/wallets/${walletId}/sign_transaction`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        eth_transaction: {
          to: '0xE9534C9fAF3cDBc636c25E1981A80EfaE03f187a',
          value: '0x38d7ea4c68000', // 0.001 ETH in wei (hex)
          nonce: '0x8',
          maxPriorityFeePerGas: '0x77359400',
          maxFeePerGas: '0xdf8475800',
          gas: '0x5208',
          chainId: '0xaa36a7' // Sepolia testnet
        }
      })
    }
  );

  const result = await response.json();
  console.log('Transaction signed:', result.signed_transaction);
  ```

  ```python Python theme={null}
  import requests
  import os

  api_key = os.environ.get('MOONKEY_SECRET_KEY')
  wallet_id = 'wallet_2Cu2uYcbwY9kcAFe2zd0P0SHftK'

  url = f"https://api.moonkey.fun/v1/wallets/{wallet_id}/sign_transaction"
  headers = {
      "Authorization": f"Bearer {api_key}",
      "Content-Type": "application/json"
  }
  payload = {
      "eth_transaction": {
          "to": "0xE9534C9fAF3cDBc636c25E1981A80EfaE03f187a",
          "value": "0x38d7ea4c68000",  # 0.001 ETH in wei (hex)
          "nonce": "0x8",
          "maxPriorityFeePerGas": "0x77359400",
          "maxFeePerGas": "0xdf8475800",
          "gas": "0x5208",
          "chainId": "0xaa36a7"  # Sepolia testnet
      }
  }

  response = requests.post(url, json=payload, headers=headers)
  result = response.json()
  print(f"Transaction signed: {result['signed_transaction']}")
  ```
</CodeGroup>

<Warning>
  You'll need to fund your wallet with Sepolia ETH for this step. Use a [Sepolia faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) to send test ETH to your wallet's `public_address`.
</Warning>

The response will contain the signature and signed transaction:

```json theme={null}
{
  "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:

<CodeGroup>
  ```javascript JavaScript theme={null}
  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);
  ```

  ```python Python theme={null}
  import requests

  signed_tx = result['signed_transaction']

  # Using a public RPC endpoint
  rpc_url = "https://rpc.sepolia.org"
  rpc_payload = {
      "jsonrpc": "2.0",
      "method": "eth_sendRawTransaction",
      "params": [signed_tx],
      "id": 1
  }

  rpc_response = requests.post(rpc_url, json=rpc_payload)
  tx_result = rpc_response.json()
  print(f"Transaction hash: {tx_result['result']}")
  ```
</CodeGroup>

<Tip>
  View your transaction on [Sepolia Etherscan](https://sepolia.etherscan.io/) by searching for the transaction hash.
</Tip>

## 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)                         |

<Info>
  Use tools like [eth-converter.com](https://eth-converter.com/) to convert between decimal and hex values for ETH amounts and gas prices.
</Info>

## Creating Solana Wallets

MoonKey also supports Solana wallets. To create a Solana wallet, simply change the `wallet_type`:

<CodeGroup>
  ```bash cURL theme={null}
  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"
    }'
  ```

  ```javascript JavaScript theme={null}
  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: 'solana',
      user_id: userId
    })
  });

  const wallet = await response.json();
  console.log('Solana wallet created:', wallet.public_address);
  ```
</CodeGroup>

## 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:

```javascript theme={null}
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?

* Check the [API Reference](/api-reference/authentication) for detailed endpoint documentation
* Review [authentication setup](/get-started/rest-api/setup) for configuration help
* Contact support for technical assistance
