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

# EVM

> Learn how to properly prepare data for EVM signing operations with Express API, including message signing and transaction data preparation.

When signing messages or data, you need to properly encode your data:

## Message Signing

For signing messages (personal signatures), encode your data as base64:

```typescript TypeScript icon="square-js" theme={null}
const personalSign = async (data: string) => {
  // Encode message as base64
  const message = Buffer.from(data, 'utf-8').toString('base64');
  
  const body = { message_base64: message };
  return await fetch('/v2/wallet/sign/message', { 
    method: 'POST', 
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
      'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
      'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
      'X-Magic-Chain': 'ETH'
    },
    body: JSON.stringify(body) 
  });
};
```

## Data Signing

For signing transaction data or other structured data, provide a keccak256 hash:

<CodeGroup>
  ```typescript Typed Data V1 theme={null}
  import { typedSignatureHash } from '@metamask/eth-sig-util';

  const signTypedDataV1 = async (data: TypedDataV1) => {
    // Compute hash for typed data V1
    const rawDataHash = typedSignatureHash(data);
    
    const body = { raw_data_hash: rawDataHash };
    return await fetch('/v2/wallet/sign/data', { 
      method: 'POST', 
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
        'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
        'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
        'X-Magic-Chain': 'ETH'
      },
      body: JSON.stringify(body) 
    });
  };
  ```

  ```typescript Typed Data V3/V4 theme={null}
  import {
    MessageTypes,
    SignTypedDataVersion,
    TypedDataUtils,
    TypedMessage,
  } from '@metamask/eth-sig-util';

  const computeEip712Hash = (
    data: TypedMessage<MessageTypes>,
    version: SignTypedDataVersion.V3 | SignTypedDataVersion.V4,
  ): string => {
    const hashBuffer = TypedDataUtils.eip712Hash(data, version);
    return '0x' + hashBuffer.toString('hex');
  };

  const signTypedDataV3 = async (data: TypedMessage<MessageTypes>) => {
    // Compute EIP-712 hash for typed data V3
    const rawDataHash = computeEip712Hash(data, SignTypedDataVersion.V3);
    
    const body = { raw_data_hash: rawDataHash };
    return await fetch('/v2/wallet/sign/data', { 
      method: 'POST', 
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
        'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
        'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
        'X-Magic-Chain': 'ETH'
      },
      body: JSON.stringify(body) 
    });
  };

  const signTypedDataV4 = async (data: TypedMessage<MessageTypes>) => {
    // Compute EIP-712 hash for typed data V4
    const rawDataHash = computeEip712Hash(data, SignTypedDataVersion.V4);
    
    const body = { raw_data_hash: rawDataHash };
    return await fetch('/v2/wallet/sign/data', { 
      method: 'POST', 
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
        'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
        'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
        'X-Magic-Chain': 'ETH'
      },
      body: JSON.stringify(body) 
    });
  };
  ```

  ```typescript Transaction Signing theme={null}
  import { resolveProperties, Signature, Transaction, TransactionLike, TransactionRequest } from 'ethers';

  const signTransaction = async (tx: TransactionRequest) => {
    // Resolve any promises in transaction properties
    const resolvedTx = await resolveProperties(tx);
    const txForSigning = { ...resolvedTx };
    delete txForSigning.from;

    // Create transaction object and get unsigned hash
    const btx = Transaction.from(txForSigning as TransactionLike);
    
    const body = { raw_data_hash: btx.unsignedHash };
    const res = await fetch('/v2/wallet/sign/data', { 
      method: 'POST', 
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
        'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
        'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
        'X-Magic-Chain': 'ETH'
      },
      body: JSON.stringify(body) 
    });
    
    const { r, s, v } = await res.json();
    
    // Attach signature to transaction
    btx.signature = Signature.from({ r, s, v });
    return btx.serialized;
  };
  ```
</CodeGroup>
