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

# getAddresses / getAddress

> Gets the client's wallet addresses for each supported chain.

## getAddresses

**Function Signature**

```swift theme={null}
public func getAddresses() async throws -> [PortalNamespace: String?]
```

You can also read the same dictionary through the `addresses` property:

```swift theme={null}
public var addresses: [PortalNamespace: String?] { get async throws }
```

**Parameters**

This method takes no parameters.

**Returns**

* **`[PortalNamespace: String?]`**: The client's addresses, keyed by namespace:
  * **`.eip155`**: The EVM address
  * **`.solana`**: The Solana address
  * **`.stellar`**: The Stellar address
  * **`.tron`**: The Tron address
  * **`.xrpl`**: The XRP Ledger classic address

Which entries are present depends on the client's wallets:

* `.eip155`, `.tron`, and `.xrpl` are present when the client has a SECP256K1 wallet.
* `.solana` and `.stellar` are present when the client has an ED25519 wallet.
* A namespace the client has no address for is left out of the dictionary, so it is not in `keys` and reads as `nil` by subscript.
* `.bip122` is never present. Read Bitcoin addresses with [`getAddress`](#getaddress) and a P2WPKH chain ID.

**Throws**

* An error if the addresses can't be read from the device's keychain.

**Example Usage**

```swift theme={null}
import PortalSwift

// `portal` is your initialized `Portal` instance.
do {
    let addresses = try await portal.getAddresses()

    if let evmAddress = addresses[.eip155] ?? nil {
        print("EVM address: \(evmAddress)")
    }
    if let xrplAddress = addresses[.xrpl] ?? nil {
        print("XRP Ledger address: \(xrplAddress)")
    }

    for (namespace, address) in addresses {
        print("\(namespace.rawValue): \(address ?? "")")
    }
} catch {
    print("Error reading addresses: \(error)")
}
```

***

## getAddress

**Function Signature**

```swift theme={null}
public func getAddress(_ forChainId: String) async -> String?
```

**Parameters**

* **`forChainId`**: A Portal chain ID, in [CAIP-2 format](../../../resources/chain-id-formatting) except for the Bitcoin P2WPKH IDs, which add a `-p2wpkh` suffix. The namespace part selects the address:

| Chain | Example chain IDs | Address returned |
| - | - | - |
| EVM | `eip155:1`, `eip155:11155111` | The EVM address |
| Solana | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | The Solana address |
| Stellar | `stellar:pubnet`, `stellar:testnet` | The Stellar address |
| Tron | `tron:mainnet`, `tron:nile` | The Tron address |
| XRP Ledger | `xrpl:0`, `xrpl:1` | The XRP Ledger classic address |
| Bitcoin mainnet | `bip122:000000000019d6689c085ae165831e93-p2wpkh` | The mainnet P2WPKH address |
| Bitcoin testnet | `bip122:000000000933ea01ad0ee984209779ba-p2wpkh` | The testnet P2WPKH address |

**Returns**

* **`String?`**: The address for that chain, or `nil` when:
  * the client has no address for that namespace,
  * the chain ID is a `bip122:` ID other than the two P2WPKH IDs above, or
  * the chain ID is malformed or its namespace isn't supported.

**Throws**

This method doesn't throw. It returns `nil` instead, including when the stored addresses can't be read. Use [`getAddresses`](#getaddresses) when you need to see errors from reading the stored addresses, such as keychain failures. A malformed or unsupported chain ID only ever produces `nil`.

**Example Usage**

```swift theme={null}
import PortalSwift

// `portal` is your initialized `Portal` instance.
let chainIds = [
    "eip155:1",
    "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
    "stellar:pubnet",
    "tron:mainnet",
    "xrpl:0",
    "bip122:000000000019d6689c085ae165831e93-p2wpkh"
]

for chainId in chainIds {
    if let address = await portal.getAddress(chainId) {
        print("\(chainId): \(address)")
    } else {
        print("\(chainId): no address")
    }
}
```

***

## PortalNamespace

```swift theme={null}
public enum PortalNamespace: String, Codable {
    case eip155
    case solana
    case bip122
    case stellar
    case tron
    case xrpl
}
```

If you `switch` exhaustively over `PortalNamespace`, add a case for `.xrpl`.

**Notes**

* Addresses come from the client's wallet metadata in the Portal API, not from the signing shares on the device. An address tells you the client has a wallet, not that it can sign on this device. Use [`isWalletOnDevice`](./iswalletondevice) to check that.
* The XRP Ledger, Stellar, and Tron addresses are derived from the client's existing wallets. No new wallet is created.
* Signing with an XRP Ledger, Stellar, or Tron chain ID isn't supported yet. `portal.request(...)` and `portal.rawSign(...)` called with one of these chain IDs throw an unsupported request method error. [Raw sign](../guide/sign-a-transaction#raw-sign) selects the key by an `eip155` (SECP256K1) or `solana` (ED25519) chain ID.
* The deprecated `portal.address` property returns `nil` when the client has no EVM address.
* `.xrpl`, `xrpl:` chain IDs, the Bitcoin P2WPKH chain IDs in `getAddress`, and the omission of namespaces without an address are available starting from SDK version 8.1.0.

**Related Documentation**

* [Create a wallet](../guide/create-a-wallet)
* [createWallet reference](./createwallet)
* [Chain ID formatting](../../../resources/chain-id-formatting)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.