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

# Sign typed data (EIP-712)

<Info>
  When using Privy's server-side SDKs to sign typed data, you can use the authorization context to
  automatically sign requests. Learn more about [signing on the
  server](/controls/authorization-keys/using-owners/sign/signing-on-the-server).
</Info>

<View title="React" icon="react">
  Use the `signTypedData` method exported from the `useSignTypedData` hook to generate an EIP-712 typed data signature with an Ethereum embedded wallet.

  ```javascript theme={"system"}
  signTypedData(input: SignTypedDataParams, options?: SignTypedDataOptions): Promise<{signature: string}>
  ```

  ### Usage

  ```tsx theme={"system"}
  import {useSignTypedData, useWallets} from '@privy-io/react-auth';

  const {signTypedData} = useSignTypedData();
  const {wallets} = useWallets();

  const {signature} = await signTypedData({...}, {
    address: wallets[0].address // Optional: Specify the wallet to use for signing. If not provided, the first wallet will be used.
  });
  ```

  ### Parameters

  <ParamField path="input" type="Object" required>
    The typed data object to sign with the wallet, with the properties defined in
    [EIP-712](https://eips.ethereum.org/EIPS/eip-712).
  </ParamField>

  <ParamField path="options" type="Object">
    <Expandable title="properties" defaultOpen="true">
      <ParamField path="uiOptions" type="SignMessageModalUIOptions">
        UI options to customize the signature prompt modal. [Learn
        more](/wallets/using-wallets/ui-components)

        <Tip>
          To hide confirmation modals, set `options.uiOptions.showWalletUIs` to `false`. Learn more
          about configuring modal prompts [here](/recipes/react/manage-wallet-UIs).
        </Tip>
      </ParamField>

      <ParamField path="address" type="string">
        Address of the wallet to use for signing the typed data. **Recommended when working with
        external wallets** to ensure reliable functionality. If not provided, the first wallet will be
        used.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Response

  {' '}

  <ResponseField name="signature" type="string">
    The signature produced by the wallet.
  </ResponseField>

  ### Callbacks

  Configure callbacks for `signTypedData` with the `useSignTypedData` hook.

  ```tsx theme={"system"}
  import {useSignTypedData} from '@privy-io/react-auth';

  const {signTypedData} = useSignTypedData({
    onSuccess: ({signature}) => {
      console.log(signature);
      // Any logic you'd like to execute after a user successfully signs the EIP-712 typed data
    },
    onError: (error) => {
      console.log(error);
      // Any logic you'd like to execute after a user exits the signing flow or there is an error
    }
  });

  // Then call `signTypedData` in your code, which will invoke these callbacks on completion
  ```

  As parameters to **`useSignTypedData`**, you may include an **`onSuccess`** callback and/or an **`onError`** callback.

  While this component is mounted, any invocation of **`signTypedData`** will trigger the **`onSuccess`** callback or **`onError`** callback on completion, depending on if the data was successfully signed or not.

  ### onSuccess

  If set, the **`onSuccess`** callback will execute after a user has successfully signed the message. Within this callback, you can access a **`signature`** parameter, which is the **`signature`** string value generated by the wallet to sign the data.

  ### onError

  If set, the **`onError`** callback will execute after a user attempts to sign the typed data and there is an error, or if the user exits the signature flow prematurely. Within this callback, you may access an **`error`** code with more information about the error.
</View>

<View title="React Native" icon="react">
  Request a message signature on the wallets Ethereum provider.

  ```javascript theme={"system"}
  request: ({method: 'eth_signTypedData_v4', params: [address, typedData]}) => Promise<{signature: string}>
  ```

  <Note>
    The Expo SDK does not support built-in UIs for signing typed data. The `eth_signTypedData_v4`
    method gives you complete control over the experience and UI.
  </Note>

  ### Usage

  ```tsx theme={"system"}
  import {useEmbeddedEthereumWallet} from '@privy-io/expo';

  const {wallets} = useEmbeddedEthereumWallet();
  const wallet = wallets[0];

  // Get an EIP-1193 Provider
  const provider = await wallet.getProvider();
  // Get address
  const accounts = await provider.request({
    method: 'eth_requestAccounts'
  });

  const signature = await provider.request({
    method: 'eth_signTypedData_v4',
    params: [accounts[0], typedData]
  });
  ```

  ### Parameters

  <ParamField path="method" type="'eth_signTypedData_v4'" required>
    The method for the wallet request. For signing messages, this is `'eth_signTypedData_v4'`.
  </ParamField>

  <ParamField path="params" type="Object" required>
    <Expandable title="properties" defaultOpen="true">
      <ParamField path="address" type="string">
        The address of the wallet to sign the message with.
      </ParamField>

      <ParamField path="typeData" type="Object" required>
        The typed data to sign with the wallet.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  {' '}

  <ResponseField name="signature" type="string">
    The signature produced by the wallet.
  </ResponseField>
</View>

<View title="Swift" icon="swift">
  To request an [EIP712](https://eips.ethereum.org/EIPS/eip-712) signature from a user's embedded wallet, send an [`eth_signTypedData_v4`](https://docs.metamask.io/wallet/reference/eth_signtypeddata_v4/) JSON-RPC request to the wallet's EIP1193 provider.

  ```swift theme={"system"}
  struct Message: Encodable {
    struct W: Encodable {
      let name: String
      let wallet: String
    }

    let from: W
    let to: W
    let contents: String
  }

  func typedData() async throws {
    let wallets = user.embeddedEthereumWallets

    // Grab the desired wallet. Here, we retrieve the first wallet
    guard let wallet = wallets.first else {
      // No ETH wallets
      return
    }

    let typedData = EthereumRpcRequest.EIP712TypedData(
      types: [
        "EIP712Domain": [
          .init("name", type: "string"),
          .init("version", type: "string"),
          .init("chainId", type: "uint256"),
          .init("verifyingContract", type: "address"),
        ],
        "Person": [
          .init("name", type: "string"),
          .init("wallet", type: "address"),
        ],
        "Mail": [
          .init("from", type: "Person"),
          .init("to", type: "Person"),
          .init("contents", type: "string"),
        ],
      ],
      primaryType: "Mail",
      domain: .init(
        name: "Ether Mail",
        version: "1",
        chainId: 1,
        verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
      ),
      message: Message(
        from: Message.W(name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"),
        to: Message.W(name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"),
        contents: "Hello, Bob!"
      )
    )

    let signature = try await provider.request(.ethSignTypedDataV4(address: wallet.address, typedData: typedData))

    print(signature)
  }
  ```

  ### Parameters

  <ParamField path="address" type="string">
    The address of the wallet to sign the message with.
  </ParamField>

  <ParamField path="typeddata" type="EthereumRpcRequest.EIP712TypedData" required>
    The typed data to sign with the wallet.

    <Expandable title="child attributes" defaultOpen="true">
      <ParamField path="types" type="[String: [EIP712Type]]" required>
        The types of the typed data, as defined by mapping the type names to
        an array of `EIP712Type` objects for each of its fields.

        Make sure to include the `EIP712Domain` type.
      </ParamField>

      <ParamField path="primaryType" type="string" required>
        The primary type of the typed data.
      </ParamField>

      <ParamField path="domain" type="EIP712Domain" required>
        The domain of the typed data, per the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) specification.
        Use the `EIP712Domain` struct to define the domain.
      </ParamField>

      <ParamField path="message" type="Encodable" required>
        The message of the typed data.
        This can be any struct that conforms to the `Encodable` protocol.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  <ResponseField name="signature" type="string">
    The signature produced by the wallet.
  </ResponseField>
</View>

<View title="Android" icon="android">
  ```kotlin theme={"system"}
  // Get Privy user
  ethereumWallet.provider.request(
    request = EthereumRpcRequest.ethSignTypedDataV4(ethereumWallet.address, typedData),
  )
  ```

  ### Parameters

  <ParamField path="method" type="'eth_signTypedData_v4'" required>
    The method for the wallet request. For signing messages, this is `'eth_signTypedData_v4'`.
  </ParamField>

  <ParamField path="params" type="Object" required>
    <Expandable title="properties" defaultOpen="true">
      <ParamField path="address" type="string">
        The address of the wallet to sign the message with.
      </ParamField>

      <ParamField path="typeData" type="Object" required>
        The typed data to sign with the wallet.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  {' '}

  <ResponseField name="signature" type="string">
    The signature produced by the wallet.
  </ResponseField>
</View>

<View title="Unity" icon="unity">
  ```csharp theme={"system"}
  try {
      IPrivyUser privyUser = await PrivyManager.Instance.GetUser();
      IEmbeddedEthereumWallet embeddedWallet = privyUser.EmbeddedEthereumWallets[0];
      var rpcRequest = new RpcRequest
      {
          Method = "eth_signTypedData_v4",
          Params = new string[] {embeddedWallet.Address, typedData }
      };
      RpcResponse signTypedDataResponse = await embeddedWallet.RpcProvider.Request(rpcRequest);
      Debug.Log(signTypedDataResponse.Data);
  } catch (PrivyWalletException ex){
      Debug.LogError($"Could not sign message due to error: {ex.Error} {ex.Message}");
  } catch (Exception ex) {
      Debug.LogError($"Could not sign message exception {ex.Message}");
  }
  ```

  ### Parameters

  <ParamField path="method" type="'eth_signTypedData_v4'" required>
    The method for the wallet request. For signing messages, this is `'eth_signTypedData_v4'`.
  </ParamField>

  <ParamField path="params" type="Object" required>
    <Expandable title="properties" defaultOpen="true">
      <ParamField path="address" type="string">
        The address of the wallet to sign the message with.
      </ParamField>

      <ParamField path="typedData" type="Object" required>
        The typed data to sign with the wallet.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  {' '}

  <ResponseField name="signature" type="string">
    The signature produced by the wallet.
  </ResponseField>
</View>

<View title="Flutter" icon="flutter">
  ```dart theme={"system"}
  // Get an EIP-1193 Provider
  final ethereumWallet = privy.user.embeddedEthereumWallets.first;
  final provider = ethereumWallet.provider;

  // Define the typed data
  final typedData = {
    'types': {
      'EIP712Domain': [
        {'name': 'name', 'type': 'string'},
        {'name': 'version', 'type': 'string'},
        {'name': 'chainId', 'type': 'uint256'},
        {'name': 'verifyingContract', 'type': 'address'},
      ],
      'Person': [
        {'name': 'name', 'type': 'string'},
        {'name': 'wallet', 'type': 'address'},
      ],
      'Mail': [
        {'name': 'from', 'type': 'Person'},
        {'name': 'to', 'type': 'Person'},
        {'name': 'contents', 'type': 'string'},
      ],
    },
    'primaryType': 'Mail',
    'domain': {
      'name': 'Ether Mail',
      'version': '1',
      'chainId': 1,
      'verifyingContract': '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
    },
    'message': {
      'from': {
        'name': 'Cow',
        'wallet': '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
      },
      'to': {
        'name': 'Bob',
        'wallet': '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
      },
      'contents': 'Hello, Bob!',
    },
  };

  // Create the RPC request
  final request = EthereumRpcRequest(
    method: 'eth_signTypedData_v4',
    params: [ethereumWallet.address, jsonEncode(typedData)],
  );

  // Sign the typed data
  final result = await provider.request(request);

  result.fold(
    onSuccess: (response) {
      final signature = response.data;
      print('Signature: $signature');
    },
    onFailure: (error) {
      print('Error signing typed data: ${error.message}');
    },
  );
  ```

  ### Parameters

  <ParamField path="method" type="'eth_signTypedData_v4'" required>
    The method for the wallet request. For signing typed data, this is `'eth_signTypedData_v4'`.
  </ParamField>

  <ParamField path="params" type="Object" required>
    <Expandable title="properties" defaultOpen="true">
      <ParamField path="address" type="string">
        The address of the wallet to sign the message with.
      </ParamField>

      <ParamField path="typedData" type="Object" required>
        The typed data to sign with the wallet.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  <ResponseField name="method" type="'eth_signTypedData_v4'">
    The RPC method executed with the wallet.
  </ResponseField>

  <ResponseField name="data" type="Object">
    Outputs for the RPC method executed with the wallet.

    <Expandable title="properties" defaultOpen="true">
      <ResponseField name="signature" type="string">
        An encoded string serializing the signature produced by the user's wallet.
      </ResponseField>
    </Expandable>
  </ResponseField>
</View>

<View title="NodeJS" icon="node-js">
  Use the `signTypedData` method on the Ethereum interface to sign a message with an Ethereum wallet.

  ### Usage

  ```tsx theme={"system"}
  // Get the signature and encoding from the response
  const {signature, encoding} = await privy
    .wallets()
    .ethereum()
    .signTypedData('insert-wallet-id', {
      params: {
        typed_data: {
          domain: {
            name: 'Ether Mail',
            version: '1',
            chainId: 1,
            verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
          },
          types: {
            EIP712Domain: [
              {name: 'name', type: 'string'},
              {name: 'version', type: 'string'},
              {name: 'chainId', type: 'uint256'},
              {name: 'verifyingContract', type: 'address'}
            ],
            Person: [
              {name: 'name', type: 'string'},
              {name: 'wallet', type: 'address'}
            ],
            Mail: [
              {name: 'from', type: 'Person'},
              {name: 'to', type: 'Person'},
              {name: 'contents', type: 'string'}
            ]
          },
          primary_type: 'Mail',
          message: {
            from: {
              name: 'Cow',
              wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
            },
            to: {
              name: 'Bob',
              wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
            },
            contents: 'Hello, Bob!'
          }
        }
      }
    });
  ```

  ### Parameters and Returns

  Check out the [API reference](/api-reference/wallets/ethereum/eth-signtypeddata-v4) for more details.
</View>

<View title="Java" icon="java">
  To sign typed data from your wallet, use the `signTypedData` method.
  It will sign your payload, and return the signature to you.

  ### Usage

  ```java theme={"system"}
  try {
      // Create typed data for EIP-712 signing
      Map<String, Object> domain = Map.of(
          "name", "Ether Mail",
          "version", "1",
          "chainId", 1,
          "verifyingContract", "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
      );

      Map<String, List<EthereumSignTypedDataRpcInputType>> types = Map.of(
          "EIP712Domain", List.of(
              EthereumSignTypedDataRpcInputType.builder().name("name").type("string").build(),
              EthereumSignTypedDataRpcInputType.builder().name("version").type("string").build(),
              EthereumSignTypedDataRpcInputType.builder().name("chainId").type("uint256").build(),
              EthereumSignTypedDataRpcInputType.builder().name("verifyingContract").type("address").build()
          ),
          "Person", List.of(
              EthereumSignTypedDataRpcInputType.builder().name("name").type("string").build(),
              EthereumSignTypedDataRpcInputType.builder().name("wallet").type("address").build()
          ),
          "Mail", List.of(
              EthereumSignTypedDataRpcInputType.builder().name("from").type("Person").build(),
              EthereumSignTypedDataRpcInputType.builder().name("to").type("Person").build(),
              EthereumSignTypedDataRpcInputType.builder().name("contents").type("string").build()
          )
      );

      Map<String, Object> message = Map.of(
          "from", Map.of(
              "name", "Cow",
              "wallet", "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
          ),
          "to", Map.of(
              "name", "Bob",
              "wallet", "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
          ),
          "contents", "Hello, Bob!"
      );

      EthereumSignTypedDataRpcInputTypedData typedData = EthereumSignTypedDataRpcInputTypedData.builder()
          .domain(domain)
          .types(types)
          .primaryType("TestMessage")
          .message(message)
          .build();

      // Example: If wallet's owner is an authorization private key
      AuthorizationContext authorizationContext = AuthorizationContext.builder()
          .addAuthorizationPrivateKey("authorization-key")
          .build();

      EthereumSignTypedDataRpcResponseData response = privyClient
          .wallets()
          .ethereum()
          .signTypedData(
              walletId,
              typedData,
              authorizationContext
          );

      String signature = response.signature();
  } catch (APIException e) {
      String errorBody = e.bodyAsString();
      System.err.println(errorBody);
  } catch (Exception e) {
      System.err.println(e.getMessage());
  }
  ```

  ### Parameters

  When defining a typed data payload, you may specify the following values on the `EthereumSignTypedDataRpcInputTypedData` builder:

  <ParamField type="Map<String, Object>" body="domain">
    The domain of the typed data payload.
  </ParamField>

  <ParamField type="Map<String, List<EthereumSignTypedDataRpcInputType>>" body="types">
    The types of the typed data payload.
  </ParamField>

  <ParamField type="Map<String, Object>" body="message">
    The message of the typed data payload.
  </ParamField>

  <ParamField type="String" body="primaryType">
    The primary type of the typed data payload.
  </ParamField>

  ### Returns

  The `EthereumSignTypedDataRpcResponseData` object contains a `signature()` field

  <ResponseField name="signature()" type="String">
    The signature produced by the wallet.
  </ResponseField>
</View>

<View title="Rust" icon="rust">
  Use the `sign_typed_data` method on the Ethereum service to sign EIP-712 typed data with an Ethereum wallet.

  ### Usage

  ```rust theme={"system"}
  use privy_rs::{AuthorizationContext, PrivyClient};

  let client = PrivyClient::new("app_id".to_string(), "app_secret".to_string())?;
  let ethereum_service = client.wallets().ethereum();
  let auth_ctx = AuthorizationContext::new();

  // Create EIP-712 typed data structure
  let typed_data = EthereumSignTypedDataRpcInputParamsTypedData {
      domain: Default::default(),
      message: Default::default(),
      primary_type: "Mail".to_string(),
      types: Default::default(),
  };

  let signature = ethereum_service
      .sign_typed_data(&wallet_id, typed_data, &auth_ctx, None)
      .await?;

  println!("Typed data signed successfully");
  ```

  ### Parameters and Returns

  See the Rust SDK documentation for detailed parameter and return types, including embedded examples:

  * [EthereumService::sign\_typed\_data](https://docs.rs/privy-rs/latest/privy_rs/ethereum/struct.EthereumService.html#method.sign_typed_data)

  For REST API details, see the [API reference](/api-reference/wallets/ethereum/eth-signtypeddata-v4).
</View>

<View title="Go" icon="golang">
  Use the `SignTypedData` method on the Ethereum service to sign EIP-712 typed data with an Ethereum wallet.

  ### Usage

  ```go theme={"system"}
  response, err := client.Wallets.Ethereum.SignTypedData(
      context.Background(),
      "wallet-id",
      privy.EthereumSignTypedDataRpcInputParams{
          TypedData: privy.EthereumSignTypedDataRpcInputParamsTypedData{
              Domain: map[string]any{
                  "name":              "Ether Mail",
                  "version":           "1",
                  "chainId":           1,
                  "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
              },
              Types: map[string][]privy.EthereumSignTypedDataRpcInputParamsTypedDataType{
                  "EIP712Domain": {
                      {Name: "name", Type: "string"},
                      {Name: "version", Type: "string"},
                      {Name: "chainId", Type: "uint256"},
                      {Name: "verifyingContract", Type: "address"},
                  },
                  "Person": {
                      {Name: "name", Type: "string"},
                      {Name: "wallet", Type: "address"},
                  },
                  "Mail": {
                      {Name: "from", Type: "Person"},
                      {Name: "to", Type: "Person"},
                      {Name: "contents", Type: "string"},
                  },
              },
              PrimaryType: "Mail",
              Message: map[string]any{
                  "from": map[string]string{
                      "name":   "Cow",
                      "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
                  },
                  "to": map[string]string{
                      "name":   "Bob",
                      "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
                  },
                  "contents": "Hello, Bob!",
              },
          },
      },
  )
  if err != nil {
      log.Fatalf("failed to sign typed data: %v", err)
  }

  fmt.Println("Signature:", response.Signature)
  ```

  ### Parameters and Returns

  See the [API reference](/api-reference/wallets/ethereum/eth-signtypeddata-v4) for more details.
</View>

<View title="Ruby" icon="gem">
  Use the `rpc` method on the `wallets` service with the `eth_signTypedData_v4` method to sign EIP-712 typed data with an Ethereum wallet.

  ### Usage

  ```ruby theme={"system"}
  typed_data = {
    domain: {
      name: "Ether Mail",
      version: "1",
      chainId: 1,
      verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
    },
    types: {
      EIP712Domain: [
        {name: "name", type: "string"},
        {name: "version", type: "string"},
        {name: "chainId", type: "uint256"},
        {name: "verifyingContract", type: "address"}
      ],
      Person: [
        {name: "name", type: "string"},
        {name: "wallet", type: "address"}
      ],
      Mail: [
        {name: "from", type: "Person"},
        {name: "to", type: "Person"},
        {name: "contents", type: "string"}
      ]
    },
    primary_type: "Mail",
    message: {
      from: {name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},
      to: {name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},
      contents: "Hello, Bob!"
    }
  }

  response = client.wallets.rpc(
    "wallet-id",
    wallet_rpc_request_body: {
      method: "eth_signTypedData_v4",
      chain_type: "ethereum",
      params: {typed_data: typed_data}
    },
    authorization_context: ctx
  )

  puts(response.data.signature)
  ```

  ### Parameters and Returns

  See the [API reference](/api-reference/wallets/ethereum/eth-signtypeddata-v4) for more details.
</View>

<View title="REST API" icon="terminal">
  To sign typed data make a POST request to

  ```bash theme={"system"}
  https://api.privy.io/v1/wallets/<wallet_id>/rpc
  ```

  ### Parameters

  <ParamField path="method" type="'eth_signTypedData_v4'" required>
    RPC method to execute with the wallet.
  </ParamField>

  <ParamField path="params" type="Object" required>
    Parameters for the RPC method to execute with the wallet.

    <Expandable title="properties" defaultOpen="true">
      <ParamField path="message" type="string" required>
        The message to sign with the wallet. If the message to sign is raw bytes, you must serialize
        the message as a hexadecimal string.
      </ParamField>

      <ParamField path="encoding" type="'utf-8' | 'hex'" required>
        The encoding format for `params.message`. Use `utf-8` for a string message and `hex` for
        bytes.
      </ParamField>
    </Expandable>
  </ParamField>

  ### Returns

  <ResponseField name="method" type="'eth_signTypedData_v4'">
    The RPC method executed with the wallet.
  </ResponseField>

  <ResponseField name="data" type="Object">
    Outputs for the RPC method executed with the wallet.

    <Expandable title="properties" defaultOpen="true">
      <ResponseField name="signature" type="string">
        An encoded string serializing the signature produced by the user's wallet.
      </ResponseField>

      <ResponseField name="encoding" type="'hex'">
        The encoding format for the returned `signature`. Currently, only `'hex'` is supported for Ethereum.
      </ResponseField>
    </Expandable>
  </ResponseField>

  ### Usage

  ```bash theme={"system"}
  curl --request POST https://api.privy.io/v1/wallets/<wallet_id>/rpc \
  -u "<your-privy-app-id>:<your-privy-app-secret>" \
  -H "privy-app-id: <your-privy-app-id>" \
  -H "privy-authorization-signature: <authorization-signature-for-request>" \
  -H 'Content-Type: application/json' \
  -d '{
    "method": "eth_signTypedData_v4",
    "params": {
      "typed_data": {
        "types": {
          "EIP712Domain": [
            { "name": "name", "type": "string" },
            { "name": "version", "type": "string" },
            { "name": "chainId", "type": "uint256" },
            { "name": "verifyingContract", "type": "address" }
          ],
          "Person": [
            { "name": "name", "type": "string" },
            { "name": "wallet", "type": "address" }
          ],
          "Mail": [
            { "name": "from", "type": "Person" },
            { "name": "to", "type": "Person" },
            { "name": "contents", "type": "string" }
          ]
        },
        "message": {
          "from": {
            "name": "Alice",
            "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
          },
          "to": {
            "name": "Bob",
            "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
          },
          "contents": "Hello, Bob!"
        },
        "primary_type": "Mail",
        "domain": {
          "name": "DApp Mail",
          "version": "1",
          "chainId": 1,
          "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
        }
      }
    }
  }'
  ```
</View>
