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

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://developers.fireblocks.com/feedback

```json
{
  "path": "/docs/add-an-exchange-account",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Add an Exchange Account

> You can easily add your own exchange account to the Fireblocks workspace, provided it's supported by Fireblocks. Once connected, you can seamlessly transfer funds between your exchange account and Fireblocks via the console or API. This guide will explain to you how to add an exchange account via our TypeScript and Python SDK.

## Prerequisites

1. Contact your CSM to enable this feature and get access to:

   1. [Get Exchange Accounts Credentials Public Key endpoint](/reference/getexchangeaccountscredentialspublickey)
   2. [Add an Exchange Account endpoint](/reference/addexchangeaccount)

2. Make sure to prepare your workspace and perform all the steps necessary [here](/reference/quickstart).

3. Install all the prerequisites for our [TypeScript](/reference/typescript-sdk) and [Python](/reference/new-python-sdk) SDK.

## Add an Exchange Account via SDK

You can use the following code to add an exchange account

<Info>
  ### Note:

  This endpoint currently only supports the following exchanges `INDEPENDENT_RESERVE`,`BIT`, `BITHUMB`, `BITSO`, `CRYPTOCOM`, `BYBIT_V2`, `WHITEBIT` , `HITBTC`, `GEMINI`, `HUOBI`, `GATEIO`, `COINHAKO`, `BULLISH`, `BITGET`, and `LUNO`
</Info>

<CodeGroup>
  ```bash bash theme={"system"}
  import base64
  import json
  from fireblocks.client import Fireblocks
  from fireblocks.client_configuration import ClientConfiguration
  from fireblocks.base_path import BasePath 
  from fireblocks.models.add_exchange_account_request import AddExchangeAccountRequest
  from cryptography.hazmat.primitives.serialization import load_pem_public_key
  from cryptography.hazmat.backends import default_backend
  from cryptography.hazmat.primitives.asymmetric import padding
  from cryptography.hazmat.primitives import hashes
  from pprint import pprint

  my_api_key="your_api_key"

  with open('your_secret_key_file_path', 'r') as file:
      secret_key_value = file.read()

  configuration = ClientConfiguration(
          api_key=my_api_key,
          secret_key=secret_key_value,
          base_path=BasePath.US #Make sure to use the correct environment. Please see the note
  )

  with Fireblocks(configuration) as fireblocks:
      tenant_id = None
      public_key = None

      try:
          # Get exchange accounts credentials public key
          api_response = fireblocks.exchange_accounts.get_exchange_accounts_credentials_public_key().result()
          tenant_id = api_response.data.tenant_id
          public_key = api_response.data.public_key
      except Exception as e:
          print("Exception when calling ExchangeAccountAPI->get_exchange_accounts_credentials_public_key: %s\n" % e)
          exit(1)

      # Credentials encryption
      exchange_api_key = "your_exchange_account_api_key"
      exchange_api_secret = 'your_exchange_account_secret_key'

      credentials = {
          "apiKey": exchange_api_key,
          "secret": exchange_api_secret,
          "tenantId": tenant_id,
      }

      pem_public_key = load_pem_public_key(bytearray(public_key, 'utf-8'), default_backend())
      credentials_str = bytes(json.dumps(credentials, separators=(',', ':')), 'utf-8')
      ciphertext = pem_public_key.encrypt(
          credentials_str,
          padding.OAEP(
              mgf=padding.MGF1(algorithm=hashes.SHA256()),
              algorithm=hashes.SHA256(),
              label=None
          )
      )
      
      encrypted_creds = bytes.decode(base64.b64encode(ciphertext))

      # Prepare add exchange account request
      add_exchange_account_request: AddExchangeAccountRequest = AddExchangeAccountRequest(            
                                      exchange_type='BIT',
                                      name='My BIT account',
                                      creds=encrypted_creds,
                                      key=exchange_api_key
      )

      try:
          # Add an exchange account
          future = fireblocks.exchange_accounts.add_exchange_account(add_exchange_account_request=add_exchange_account_request)
          api_response = future.result()  # Wait for the response
          print("The response of ExchangeAccountAPI->add_exchange_account:\n")
          pprint(api_response.data.to_json())
      except Exception as e:
          print("Exception when calling ExchangeAccountAPI->add_exchange_account: %s\n" % e)
  ```

  ```bash bash theme={"system"}
  import { readFileSync } from 'fs';
  import { Fireblocks, BasePath, ExchangeAccountsApiAddExchangeAccountRequest } from "@fireblocks/ts-sdk";
  import { webcrypto } from "crypto";
  const crypto = webcrypto;

  const EXCHANGE_API_KEY = "exchange_api_key";
  const EXCHANGE_API_SECRET = "exchange_api_secret";

  const FIREBLOCKS_API_SECRET_PATH = "./fireblocks_secret.key";

  const fireblocks = new Fireblocks({
      apiKey: "my-api-key",
      basePath: BasePath.US, //make sure to use the correct environment. Please see the note
      secretKey: readFileSync(FIREBLOCKS_API_SECRET_PATH, "utf8"),
  });

  async function getExchangeAccountsCredentialsPublicKey() {
      return (await fireblocks.exchangeAccounts.getExchangeAccountsCredentialsPublicKey()).data;
  }

  function str2ab(str: string): ArrayBuffer {
      const buf = new ArrayBuffer(str.length);
      const bufView = new Uint8Array(buf);
      for (let i = 0, strLen = str.length; i < strLen; i++) {

          bufView[i] = str.charCodeAt(i);
      }
      return buf;
  };

  function arrayBufferToBase64(buffer: ArrayBuffer): string {
      const bytes = new Uint8Array(buffer);
      let binary = '';
      for (let i = 0; i < bytes.length; i++) {
          binary += String.fromCharCode(bytes[i]);
      }
      return btoa(binary);
  }

  async function encryptCredentials(publicKey: string, payload: any) {
      const pemHeader = '-----BEGIN PUBLIC KEY-----\n';
      const pemFooter = '\n-----END PUBLIC KEY-----';
      const extractedCode = publicKey.substring(pemHeader.length, publicKey.length - pemFooter.length);
      const binaryDerString = atob(extractedCode);
      const binaryDer = str2ab(binaryDerString);

      const cryptoPublicKey = await crypto.subtle.importKey(
          'spki',
          binaryDer,
          {
              name: 'RSA-OAEP',
              hash: 'SHA-256',
          },
          true,
          ['encrypt'],
      );

      const payloadStr = JSON.stringify(payload);
      const encodedDataString = new TextEncoder().encode(payloadStr);

      const encryptedData = await crypto.subtle.encrypt(
          {
              name: 'RSA-OAEP',
          },
          cryptoPublicKey,
          encodedDataString,
      );

      const encryptedDatab64 = arrayBufferToBase64(encryptedData);

      return encryptedDatab64;
  }

  async function main() {

      try {
          const credsPublicKey = await getExchangeAccountsCredentialsPublicKey();

          let credentials_payload = {
              "apiKey": EXCHANGE_API_KEY,
              "secret": EXCHANGE_API_SECRET,
              "tenantId": credsPublicKey.tenantId,
          };

          const encryptedCredentials = await encryptCredentials(credsPublicKey.publicKey, credentials_payload);

          const request: ExchangeAccountsApiAddExchangeAccountRequest = {
              addExchangeAccountRequest: {
                  name: "My BIT account",
                  exchangeType: "BIT",
                  creds: encryptedCredentials,
                  key: EXCHANGE_API_KEY
              }
          };

          const addExchangeResponse = await fireblocks.exchangeAccounts.addExchangeAccount(request);
          console.log(addExchangeResponse);
      } catch (e) {
          console.log(e)
      }
  }

  (async () => {
      await main();
  })();
  ```
</CodeGroup>

<Info>
  ### Note:

  Make sure you're using the correct value for the API base URL for your environment:

  * `BasePath.US` - for production workspaces
  * `BasePath.Sandbox` - for sandbox workspaces\`
</Info>
