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

# Crypto Addresses

> Register wallet addresses for Travel Rule compliance before using them in any Autoramp flow.

Every wallet address that interacts with Iron must be registered (linked) to a customer **before** it can be used in any Autoramp flow — [onramp](/onramp), [offramp](/offramp), or [swap](/swap). This is a regulatory requirement under the **[Travel Rule](/travel-rule)**, which obliges Virtual Asset Service Providers to exchange originator and beneficiary information for crypto transfers.

Iron supports two wallet types:

* **Self-hosted wallets** — the customer controls the private key. Registration requires a signed proof-of-ownership message.
* **Hosted wallets** — the wallet is custodied by another VASP (e.g. Coinbase, Kraken). Registration requires the VASP's DID so Iron can exchange travel-rule data with the custodian.

<Warning>
  Autoramp creation will fail if the recipient wallet address has not been registered first.
</Warning>

## Verify a self-hosted crypto address

Submit a signature proving ownership of your cryptocurrency wallet. The verification process requires signing a specific message with your wallet's private key.

<Steps>
  <Step title="Format the proof message:">
    ```bash theme={null}
    I am verifying ownership of the wallet address {wallet_address} as customer {customer_id}. This message was signed on {date} to confirm my control over this wallet.
    ```

    Replace:

    * `{customer_id}` with your customer ID
    * `{wallet_address}` with your wallet address
    * `{date}` with today's date in DD/MM/YYYY format using UTC timezone

    Example:

    ```bash theme={null}
    I am verifying ownership of the wallet address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e as customer 4b85d15e-f343-41c0-809c-85314cae2fa6. This message was signed on 23/05/2025 to confirm my control over this wallet.
    ```
  </Step>

  <Step title="Sign this message using your wallet's private key" />

  <Step title="Submit the proof:">
    <CodeGroup>
      ```bash Bash theme={null}
      curl -X POST https://api.sandbox.iron.xyz/api/addresses/crypto/selfhosted \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 123e4567-e89b-12d3-a456-426614174000" \
      -H "X-API-Key: $API_KEY" \
      -d '{
        "customer_id": "4b85d15e-f343-41c0-809c-85314cae2fa6",
        "address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "message": "I am verifying ownership of the wallet address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e as customer 4b85d15e-f343-41c0-809c-85314cae2fa6. This message was signed on 23/05/2025 to confirm my control over this wallet.",
        "signature": "0xa5f1751b75a28c12694f02590d29b8cdd68b4f5c783273a75823fc6cfeaa702f1a65fa7c1838ae799fe755c92443cb51631d000922329cdd2ce799eee75f42531b",
        "blockchain": "Ethereum"
      }'
      ```
    </CodeGroup>
  </Step>
</Steps>

<Note>
  The date must be **today** in DD/MM/YYYY using the UTC timezone (not your local timezone, not a stale year from a template). If you sign before UTC midnight and submit after, re-sign.
</Note>

<Note>
  The message must be **byte-identical** between sign-time and POST-time (no rewording, no trailing newline, no whitespace edits), and the `customer_id` inside the message must equal the `customer_id` in the request body. EVM signatures use standard EIP-191 `personal_sign` (the default for `cast wallet sign`, ethers `signMessage`, viem `signMessage`); smart-contract wallets verify via EIP-1271. You can add additional text before or after the required message and verification still succeeds.
</Note>

## Register a hosted wallet

When the recipient wallet is custodied by another institution (VASP) — for example Coinbase, Kraken, or Binance — you need to register the wallet address along with the institution's DID so Iron can exchange travel-rule data with the custodian.

<Steps>
  <Step title="Search for the VASP (wallet provider):">
    First, find the DID (Decentralized Identifier) of the institution that hosts the wallet:

    <CodeGroup>
      ```bash Bash theme={null}
      curl -X GET "https://api.sandbox.iron.xyz/api/addresses/crypto/hosted/vasps?q=bitstamp&limit=10" \
      -H "X-API-Key: $API_KEY"
      ```
    </CodeGroup>

    Response:

    ```json theme={null}
    [
      {
        "did": "did:ethr:0x367f004f1062f68c038ac8d3c3071fedc18fb689",
        "name": "Bitstamp",
        "country": "LU",
        "website": "https://www.bitstamp.net/"
      }
    ]
    ```
  </Step>

  <Step title="Register the hosted wallet address:">
    Submit the wallet address with the VASP's DID:

    <CodeGroup>
      ```bash Bash theme={null}
      curl -X POST https://api.sandbox.iron.xyz/api/addresses/crypto/hosted \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 123e4567-e89b-12d3-a456-426614174001" \
      -H "X-API-Key: $API_KEY" \
      -d '{
        "customer_id": "4b85d15e-f343-41c0-809c-85314cae2fa6",
        "wallet_address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "vasp_did": "did:ethr:0x367f004f1062f68c038ac8d3c3071fedc18fb689",
        "blockchain": "Ethereum"
      }'
      ```
    </CodeGroup>
  </Step>
</Steps>

The registration requires:

* `customer_id`: The customer's UUID
* `wallet_address`: The wallet address at the institution
* `vasp_did`: The DID (Decentralized Identifier) of the institution hosting the wallet (obtained from the VASP search)
* `blockchain`: The blockchain the address is on (e.g. `Ethereum`, `Solana`, `Polygon`, `Base`, `Arbitrum`)

<Note>
  The wallet must be registered in your name at the hosting institution. Iron will use the VASP DID to exchange travel rule information with the institution.
</Note>

## List verified addresses

Retrieve all verified cryptocurrency addresses for a customer:

<CodeGroup>
  ```bash Bash theme={null}
  curl -X GET https://api.sandbox.iron.xyz/api/addresses/crypto/{customer_id} \
  -H "X-API-Key: $API_KEY"
  ```
</CodeGroup>

Optionally filter by address type using the `filter` query parameter:

* `?filter=Hosted`: Only hosted wallet addresses
* `?filter=SelfHosted`: Only self-hosted wallet addresses
* `?filter=All` or no filter: All addresses (default)

Example with filter:

<CodeGroup>
  ```bash Bash theme={null}
  curl -X GET "https://api.sandbox.iron.xyz/api/addresses/crypto/4b85d15e-f343-41c0-809c-85314cae2fa6?filter=SelfHosted" \
  -H "X-API-Key: $API_KEY"
  ```
</CodeGroup>

The response includes details about each verified address:

* `id`: Address ID
* `wallet_address`: The wallet address
* `address_type`: "Hosted" or "SelfHosted"
* `blockchain`: The blockchain (e.g. "Ethereum", "Solana")
* `created_at`: Registration timestamp
* `disabled`: Whether the address is disabled
* `vasp_did`: (For hosted wallets only) The VASP's DID
* `proof_message`: (For self-hosted wallets only) The verification message
* `proof_signature`: (For self-hosted wallets only) The signature

Common error scenarios:

* Invalid proof message format
* Incorrect date in proof message (must be today's date in DD/MM/YYYY format)
* Invalid signature
* Wallet address already registered
* Invalid blockchain/address format mismatch
* Customer ID does not belong to your partner

## Disable or enable an address

You can disable or enable a verified crypto address. Disabled addresses cannot be used for transactions.

<CodeGroup>
  ```bash Bash theme={null}
  curl -X PUT https://api.sandbox.iron.xyz/api/addresses/crypto/{address_id}/disabled \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d '{
    "customer_id": "4b85d15e-f343-41c0-809c-85314cae2fa6",
    "disabled": true
  }'
  ```
</CodeGroup>

<Note>
  Addresses that were automatically disabled due to high risk (e.g., flagged by Chainalysis) cannot be re-enabled.
</Note>

## Related guides

<CardGroup>
  <Card title="Fiat Sources Verification" horizontal icon="shield" href="/fiat-addresses" />

  <Card title="Travel Rule Compliance" horizontal icon="plane" href="/travel-rule" />
</CardGroup>
