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

# Add Wallet Operations to Your Application

> Integrate WalletSuite into your backend — balances, prices, fees, and unsigned transaction payloads — via the TypeScript SDK or REST API.

**Time:** 10-15 minutes.

Integrate from TypeScript via the SDK, or from any language via the REST API. Either way, run it server-side — keys and signing stay on your infrastructure. WalletSuite returns unsigned transaction payloads you sign with your existing signer (KMS, HSM, custodian, or a local wallet).

## What Your Application Will Be Able to Do

* Query any wallet's balance across [multiple chains](/supported-chains) with fiat valuations
* Look up token prices in real-time
* Estimate transaction fees before executing
* Prepare unsigned transaction payloads for your signing infrastructure
* Resolve token contract addresses from symbols or names

## Prerequisites

* WalletSuite API key — see [Credentials & Authentication](/getting-started/prerequisites/credentials-and-authentication)
* One of: Node.js 18+ (for the TypeScript SDK), Python 3.9+ with `requests`, or any HTTP client (`curl`, Go's `net/http`, Ruby's `net/http`, etc.)

## Step 1 — Install

<CodeGroup>
  ```bash TypeScript SDK theme={null}
  npm install @walletsuite/wallet-sdk
  ```

  ```bash Python theme={null}
  pip install requests
  ```

  ```bash cURL theme={null}
  # No install — curl ships with macOS, Linux, and Windows 10+.
  ```
</CodeGroup>

## Step 2 — Initialize the Client

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  import { WalletSuiteSDK } from "@walletsuite/wallet-sdk";

  const sdk = new WalletSuiteSDK({
    apiKey: process.env.WALLETSUITE_API_KEY!,
    env: "prod",
  });
  ```

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

  session = requests.Session()
  session.headers.update({
      "x-api-key": os.environ["WALLETSUITE_API_KEY"],
      "content-type": "application/json",
  })
  BASE_URL = "https://api.walletsuite.io"
  ```

  ```bash cURL theme={null}
  export WALLETSUITE_API_KEY="your-key-here"
  export WALLETSUITE_BASE_URL="https://api.walletsuite.io"
  ```
</CodeGroup>

<Warning>
  Store your API key in an environment variable or secret manager. Do not hardcode it in source files.
</Warning>

## Step 3 — Query a Balance

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  const balance = await sdk.api.getNativeBalance("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "ethereum", "USD");

  console.log(balance.data);
  // { chain: "ethereum", symbol: "ETH", amount: "1234.56", fiatValue: "3950000.00", ... }
  ```

  ```python Python theme={null}
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  response = session.get(
      f"{BASE_URL}/api/balance/{address}",
      params={"chain": "ethereum", "fiat": "USD"},
  )
  print(response.json()["data"])
  # { "chain": "ethereum", "symbol": "ETH", "amount": "1234.56", "fiatValue": "3950000.00", ... }
  ```

  ```bash cURL theme={null}
  curl "$WALLETSUITE_BASE_URL/api/balance/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045?chain=ethereum&fiat=USD" \
    -H "x-api-key: $WALLETSUITE_API_KEY"
  ```
</CodeGroup>

For all token balances on a chain:

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  const balances = await sdk.api.getAssetBalances("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", {
    chain: "ethereum",
    fiat: "USD",
    includeNative: true,
  });

  console.log(balances.data.totalFiatValue); // "4,120,000.00"
  console.log(balances.data.assets);         // [{ symbol: "ETH", ... }, { symbol: "USDT", ... }]
  ```

  ```python Python theme={null}
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  response = session.get(
      f"{BASE_URL}/api/balances/{address}",
      params={"chain": "ethereum", "fiat": "USD", "includeNative": "true"},
  )
  data = response.json()["data"]
  print(data["totalFiatValue"])  # "4,120,000.00"
  print(data["assets"])          # [{ "symbol": "ETH", ... }, { "symbol": "USDT", ... }]
  ```

  ```bash cURL theme={null}
  curl "$WALLETSUITE_BASE_URL/api/balances/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045?chain=ethereum&fiat=USD&includeNative=true" \
    -H "x-api-key: $WALLETSUITE_API_KEY"
  ```
</CodeGroup>

## Step 4 — Get a Price

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  // By symbol
  const ethPrice = await sdk.api.getPriceBySymbol("ETH");
  console.log(ethPrice.value); // "3200.42"

  // By contract address
  const usdtPrice = await sdk.api.getPriceByContract(
    "0xdAC17F958D2ee523a2206206994597C13D831ec7",
    "ethereum"
  );
  ```

  ```python Python theme={null}
  # By symbol
  eth_price = session.get(f"{BASE_URL}/api/price/ETH").json()
  print(eth_price["value"])  # "3200.42"

  # By contract address
  usdt_price = session.get(
      f"{BASE_URL}/api/price/by-contract/0xdAC17F958D2ee523a2206206994597C13D831ec7",
      params={"chain": "ethereum"},
  ).json()
  ```

  ```bash cURL theme={null}
  # By symbol
  curl "$WALLETSUITE_BASE_URL/api/price/ETH" \
    -H "x-api-key: $WALLETSUITE_API_KEY"

  # By contract address
  curl "$WALLETSUITE_BASE_URL/api/price/by-contract/0xdAC17F958D2ee523a2206206994597C13D831ec7?chain=ethereum" \
    -H "x-api-key: $WALLETSUITE_API_KEY"
  ```
</CodeGroup>

## Step 5 — Estimate Fees

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  const feeQuote = await sdk.api.quoteTransferFee({
    chain: "ethereum",
    from: "0xabc...",
    to: "0xdef...",
    amountWei: "1500000000000000000", // 1.5 ETH in wei
    fiat: "USD",
  });

  console.log(feeQuote.data);
  // { chain: "ethereum", feeSymbol: "ETH", feeAmount: 0.002, fiatValue: 6.40, ... }
  ```

  ```python Python theme={null}
  response = session.post(
      f"{BASE_URL}/api/fees/quote",
      json={
          "chain": "ethereum",
          "from": "0xabc...",
          "to": "0xdef...",
          "amountWei": "1500000000000000000",  # 1.5 ETH in wei
      },
  )
  print(response.json()["data"])
  # { "chain": "ethereum", "feeSymbol": "ETH", "feeAmount": "0.002", "fiatValue": "6.40", ... }
  ```

  ```bash cURL theme={null}
  curl -X POST "$WALLETSUITE_BASE_URL/api/fees/quote" \
    -H "x-api-key: $WALLETSUITE_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "chain": "ethereum",
      "from": "0xabc...",
      "to": "0xdef...",
      "amountWei": "1500000000000000000"
    }'
  ```
</CodeGroup>

## Step 6 — Prepare a Transfer

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  const prepared = await sdk.api.prepareTransferSign({
    chain: "ethereum",
    txType: "TRANSFER_NATIVE",
    from: "0xabc...",
    to: "0xdef...",
    amount: "1.5", // Human-readable ETH
  });

  console.log(prepared.data);
  // { nonce, gasLimit, maxFeePerGas, value, data, estimatedFee, estimatedFeeInUsd, ... }
  ```

  ```python Python theme={null}
  response = session.post(
      f"{BASE_URL}/api/txs/prepare-sign",
      json={
          "chain": "ethereum",
          "txType": "TRANSFER_NATIVE",
          "from": "0xabc...",
          "to": "0xdef...",
          "amount": "1.5",  # Human-readable ETH
      },
  )
  prepared = response.json()
  # { nonce, gasLimit, maxFeePerGas, value, data, estimatedFee, estimatedFeeInUsd, ... }
  ```

  ```bash cURL theme={null}
  curl -X POST "$WALLETSUITE_BASE_URL/api/txs/prepare-sign" \
    -H "x-api-key: $WALLETSUITE_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "chain": "ethereum",
      "txType": "TRANSFER_NATIVE",
      "from": "0xabc...",
      "to": "0xdef...",
      "amount": "1.5"
    }'
  # { nonce, gasLimit, maxFeePerGas, value, data, estimatedFee, estimatedFeeInUsd, ... }
  ```
</CodeGroup>

The response contains everything your signing infrastructure needs: nonce, gas parameters, calldata, and value. Sign this payload with your own key management (HSM, KMS, or any signer) and broadcast via your infrastructure or the WalletSuite API.

### Token Transfers

For ERC-20 token transfers, resolve the contract first:

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  // 1. Resolve the token
  const assets = await sdk.api.listAssets("ethereum");
  const tokenContract = assets.data?.find((a) => a.symbol === "USDT")?.id;

  // 2. Prepare the transfer
  const prepared = await sdk.api.prepareTransferSign({
    chain: "ethereum",
    txType: "TRANSFER_TOKEN",
    from: "0xabc...",
    to: "0xdef...",
    amount: "100",
    tokenContract,
  });
  ```

  ```python Python theme={null}
  # 1. Resolve the token
  asset = session.get(
      f"{BASE_URL}/api/assets",
      params={"chain": "ethereum", "symbol": "USDT"},
  ).json()
  token_contract = asset["data"][0]["id"]

  # 2. Prepare the transfer
  prepared = session.post(
      f"{BASE_URL}/api/txs/prepare-sign",
      json={
          "chain": "ethereum",
          "txType": "TRANSFER_TOKEN",
          "from": "0xabc...",
          "to": "0xdef...",
          "amount": "100",
          "tokenContract": token_contract,
      },
  ).json()
  ```

  ```bash cURL theme={null}
  # 1. Resolve the token (read .data[0].id from the response)
  curl "$WALLETSUITE_BASE_URL/api/assets?chain=ethereum&symbol=USDT" \
    -H "x-api-key: $WALLETSUITE_API_KEY"

  # 2. Prepare the transfer with the resolved tokenContract
  curl -X POST "$WALLETSUITE_BASE_URL/api/txs/prepare-sign" \
    -H "x-api-key: $WALLETSUITE_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "chain": "ethereum",
      "txType": "TRANSFER_TOKEN",
      "from": "0xabc...",
      "to": "0xdef...",
      "amount": "100",
      "tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
    }'
  ```
</CodeGroup>

## Error Handling

The SDK throws a typed `ApiError` carrying the HTTP `status`; the REST API returns the `ApiResponse` envelope (`ok`, `code`, `message`) alongside that status. Branch on it:

<CodeGroup>
  ```typescript TypeScript SDK theme={null}
  import { ApiError } from "@walletsuite/wallet-sdk";

  try {
    const balance = await sdk.api.getNativeBalance(address, chain);
  } catch (error) {
    if (!(error instanceof ApiError)) throw error;
    switch (error.status) {
      case 400:
        // Fix input (bad address, invalid chain)
        break;
      case 401:
      case 403:
        // Check API key, or feature not enabled on your plan
        break;
      case 429:
        // Back off, retry later
        break;
      default:
        if (error.status && error.status >= 500) {
          // Retry with backoff (transient upstream error)
        }
    }
  }
  ```

  ```python Python theme={null}
  response = session.get(f"{BASE_URL}/api/balance/{address}", params={"chain": chain})

  if not response.ok:
      code = response.json().get("code")  # error code from the ApiResponse envelope
      if response.status_code == 400:
          ...  # Fix input (bad address, invalid chain)
      elif response.status_code in (401, 403):
          ...  # Check API key, or feature not enabled on your plan (see code)
      elif response.status_code == 429:
          ...  # Back off, retry later
      elif response.status_code >= 500:
          ...  # Retry with backoff (transient upstream error)
  ```

  ```bash cURL theme={null}
  # Capture the HTTP status; non-2xx responses carry an error envelope { "ok": false, "code", "message" }.
  curl -sS -o response.json -w "%{http_code}" \
    "$WALLETSUITE_BASE_URL/api/balance/$ADDRESS?chain=ethereum" \
    -H "x-api-key: $WALLETSUITE_API_KEY"
  # 400 = validation · 401/403 = auth / plan · 429 = rate limit · 5xx = retry
  ```
</CodeGroup>

See [SDK Error Handling](/sdk/error-handling) for the full error taxonomy and handling patterns.

## Architecture Recommendation

Run the SDK server-side, not in the browser. The integration shape:

```text theme={null}
Browser → Your Server → WalletSuite SDK → unsigned tx payload
                                   │
                                   ▼
                                   Your signer (KMS / HSM / custodian / local wallet)
                                   │
                                   ▼
                                   Signed tx → WalletSuite API or your own RPC → Blockchain
```

This keeps your API key on the server, keeps signing inside your existing key infrastructure, and lets you add your own auth, rate limiting, and business logic between the user and WalletSuite. The SDK never sees keys or signed payloads — it returns typed unsigned payloads with everything your signer needs (nonce, gas parameters, calldata, value).

## Next Steps

* [End-to-End Token Transfer](/sdk/end-to-end-token-transfer-flow) — complete signing and broadcast flow
* [Integration Samples](/sdk/integration-samples) — 20+ code examples
* [SDK Error Handling](/sdk/error-handling) — detailed error patterns
* [API Reference](/getting-started/api-reference/overview) — full REST API with interactive playground
