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

# Admin Security

> Secure wallet management and studio security best practices

## Wallet Management

### Wallet Types

| Wallet Type | Purpose | Security Level |
| - | - | - |
| **Developer Wallet** | Testing, deploying to testnet | Low (hot wallet OK) |
| **Deployer Wallet** | Mainnet contract deployment | Medium (hardware wallet) |
| **Treasury Wallet** | Holding funds, revenue | High (multisig) |
| **Minter Wallet** | Backend minting operations | Medium (server-side) |

### Developer Wallet Setup

For local development and testnet:

#### MetaMask Setup

1. Install [MetaMask](https://metamask.io)
2. Add Immutable Chain Testnet:
   * Network Name: `Immutable Testnet`
   * RPC: `https://rpc.testnet.immutable.com`
   * Chain ID: `13473`
   * Symbol: `tIMX`
3. Get test tokens from the [Faucet](https://hub.immutable.com/faucet)

#### Hardhat Configuration

```typescript theme={null}
// hardhat.config.ts
import { HardhatUserConfig } from 'hardhat/config';

const config: HardhatUserConfig = {
<HardhatNetworkConfig />
};

export default config;
```

> [!WARNING]
>
> **Never commit `.env` files to version control.** Add `.env` and `.env.local` to your `.gitignore` file to prevent accidentally exposing private keys or API secrets.

## Production Treasury: Multisig

For production funds, use a multisig wallet like [Safe](https://safe.global).

### Why Multisig?

* **No single point of failure**: Multiple signatures required
* **Team accountability**: Track who approved transactions
* **Recovery**: Lost keys don't mean lost funds

### Setting Up Safe

1. Go to [Safe](https://app.safe.global)
2. Connect to Immutable Chain
3. Create a new Safe with:
   * Multiple owner addresses (team members)
   * Threshold (e.g., 2 of 3 signatures required)
4. Fund the Safe with IMX for gas

### Transaction Flow

```
Team Member A proposes transaction
    ↓
Team Member B reviews and signs
    ↓
Threshold reached → Transaction executes
```

## Backend Minting Wallet

Your backend needs a wallet for minting operations.

### Key Management Options

| Option | Pros | Cons |
| - | - | - |
| **Environment Variable** | Simple | Less secure |
| **AWS KMS** | Secure, auditable | More complex |
| **HashiCorp Vault** | Enterprise-grade | Infrastructure overhead |

### Using AWS KMS with viem

```typescript theme={null}
import { KMSClient, SignCommand } from '@aws-sdk/client-kms';
import { createWalletClient, http, type Account } from 'viem';
import { immutableZkEvm } from 'viem/chains';

// Create a KMS-backed account for viem
async function createKMSAccount(keyId: string): Promise<Account> {
  const kms = new KMSClient({ region: 'us-east-1' });

  return {
    address: '0x...', // Derive from KMS public key
    type: 'local',
    signMessage: async ({ message }) => {
      const command = new SignCommand({
        KeyId: keyId,
        Message: Buffer.from(message as string),
        SigningAlgorithm: 'ECDSA_SHA_256',
        MessageType: 'DIGEST',
      });
      const response = await kms.send(command);
      // Process and return signature
      return '0x...' as `0x${string}`;
    },
    signTransaction: async (tx) => {
      // Sign transaction with KMS
      return '0x...' as `0x${string}`;
    },
    signTypedData: async (data) => {
      // Sign typed data with KMS
      return '0x...' as `0x${string}`;
    },
  };
}

// Use with viem
const account = await createKMSAccount(process.env.KMS_KEY_ID!);
const walletClient = createWalletClient({
  account,
  chain: immutableZkEvm,
  transport: http(),
});
```

### Rate Limiting & Monitoring

Protect your minting wallet:

```typescript theme={null}
import rateLimit from 'express-rate-limit';

const mintLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 100, // 100 requests per minute
  message: 'Too many mint requests',
});

app.post('/api/mint', mintLimiter, async (req, res) => {
  // Log all mint operations
  logger.info('Mint request', {
    recipient: req.body.address,
    tokenId: req.body.tokenId,
    timestamp: new Date(),
  });
  
  // Process mint...
});
```

## Security Checklist

### Development

* [ ] Use separate wallet for testnet
* [ ] Never use mainnet private keys in development
* [ ] Clear browser wallet state between projects

### Production

* [ ] Treasury in multisig (Safe)
* [ ] Deployer wallet on hardware device
* [ ] Minting wallet keys in secure storage (KMS/Vault)
* [ ] Rate limiting on minting endpoints
* [ ] Monitoring and alerts for unusual activity
* [ ] Regular key rotation schedule
* [ ] Incident response plan documented

## Gas Management

### Estimating Costs

```typescript theme={null}
import { createPublicClient, http, formatEther } from 'viem';
import { immutableZkEvm } from 'viem/chains';

const publicClient = createPublicClient({
  chain: immutableZkEvm,
  transport: http(),
});

async function estimateGas(to: `0x${string}`, data: `0x${string}`) {
  const gasEstimate = await publicClient.estimateGas({ to, data });
  const gasPrice = await publicClient.getGasPrice();
  
  const maxCost = gasEstimate * gasPrice;
  console.log(`Max cost: ${formatEther(maxCost)} IMX`);
}
```

### Maintaining Balance

Set up alerts when wallet balance drops:

```typescript theme={null}
import { createPublicClient, http, formatEther, parseEther } from 'viem';
import { immutableZkEvm } from 'viem/chains';

const publicClient = createPublicClient({
  chain: immutableZkEvm,
  transport: http(),
});

async function checkBalance(address: `0x${string}`, threshold: bigint) {
  const balance = await publicClient.getBalance({ address });
  
  if (balance < threshold) {
    await sendAlert(`Wallet ${address} balance low: ${formatEther(balance)} IMX`);
  }
}

// Run periodically
setInterval(() => checkBalance(MINTER_WALLET, parseEther('10')), 60000);
```

## Funds Recovery

### From Passport Wallet

Players control their Passport wallets. Recovery is through their authentication provider (Google, Apple, etc.).

### From Studio Wallets

* **Multisig**: Recover with threshold of remaining signers
* **Single-sig**: Depends on backup strategy
* **KMS**: AWS manages key durability

> [!TIP]
>
> Always test your recovery procedures before you need them.

## Next Steps

> [card] [Contracts](https://docs.immutable.com/docs/products/asset-contracts/overview.md)
>
> Deploy contracts from your secure wallet

> [card] [Minting](https://docs.immutable.com/docs/products/asset-contracts/erc721.md)
>
> Set up backend minting


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.