# Creating Wallets

In order to get wallets, please ensure that you have [registered and installed the Caishen SDK](https://docs.caishen.tech/registration).

With the Caishen SDK, you can create wallets for:

* EVM
* Bitcoin
* Solana
* SUI
* XRP

{% hint style="info" %}
All Caishen wallets come with support for crosschain swaps and sending&#x20;
{% endhint %}

#### 🔍 Get Wallet Info

Fetch a wallet associated with a user or agent for a specific chain.

> ⚠️ Note: The privateKey will only be returned if the developer dashboard has explicitly allowed access. With it, you can construct your own signer. If not enabled, the SDK will only return the public data needed to interact via Caishen.

**📥 Parameters**

| Name        | Type   | Required | Description                                  |
| ----------- | ------ | -------- | -------------------------------------------- |
| `chainType` | string | ✅        | Blockchain type (`ETHEREUM`, `SOLANA`, etc.) |
| `chainId`   | number | ❌        | Optional chain ID (e.g., 1 for Ethereum)     |
| `account`   | number | ✅        | Account index or identifier                  |

**📘 Example**

```
wallet = await sdk.crypto.get_wallet({
    "chainType": "ETHEREUM",
    "chainId": 1,
    "account": 0
})
```

**📚 Type: `IWalletAccount`**

```
class IWalletAccount:
  address: str
  chainType: str
  publicKey: str
  privateKey: Optional(str)  # Only returned if access is enabled in the dashboard
  account: int
```

> ⚠️ Private key is optional and only available if explicitly enabled in the dashboard.

#### MinimalWalletInput

```
class MinimalWalletInput:
  account: int
  chainType: str
  address: str
```

Used for all `cash` and `swap` functions to avoid sending sensitive data.

#### 🌐 Supported Chains

Returns the list of all chain types supported by the backend for wallet creation.

**📦 Returns**

```
List[str] // e.g., ['evm', 'solana']
```

**📘 Example**

```
chains = await sdk.crypto.get_supported_chain_types()
```

#### 🔗 Get EVM RPC URL

Returns the public RPC endpoint URL for a given EVM-compatible chain ID.

#### 📥 Parameters

| Name      | Type     | Required | Description         |
| --------- | -------- | -------- | ------------------- |
| `chainId` | ChainIds | ✅        | Chain ID enum value |

#### 📦 Returns

```
rpc_url = await sdk.crypto.get_rpc(1)
```

***

### 💸 Token Operations

#### ➕ Send Token

Send a token or native coin (like ETH, MATIC, SOL) to another address.

**📥 Parameters**

| Name      | Type                                                                   | Required | Description                               |
| --------- | ---------------------------------------------------------------------- | -------- | ----------------------------------------- |
| `wallet`  | `IWalletAccount`                                                       | ✅        | Wallet object returned from `getWallet()` |
| `payload` | `{ token?: string; amount: string; toAddress: string; memo?: number }` | ✅        | Transfer details                          |

> 🚫 Do not pass the full `IWalletAccount` into this function — only `MinimalWalletInput` is required and safer.

* If `payload.token` is **undefined**, the function sends the **native gas token** (e.g. ETH, MATIC).
* If `payload.token` is provided, it sends that **ERC20 or token** instead.

**📦 Returns**

```
'transaction_hash'
```

**📘 Example**

```
tx_hash = await sdk.crypto.send({
    "wallet": wallet,
    "payload": {
        "token": "0xTokenAddress",  # Optional
        "amount": "0.5",
        "toAddress": "0xRecipientAddress"
    }
})
```

#### 📊 Get Balance

Fetch the balance of a wallet for either the **native coin** or a specific **token**.

**📥 Parameters**

| Name      | Type                 | Required | Description                                                               |
| --------- | -------------------- | -------- | ------------------------------------------------------------------------- |
| `wallet`  | `IWalletAccount`     | ✅        | Wallet object                                                             |
| `payload` | `{ token?: string }` | ❌        | If `token` is provided, fetch its balance; otherwise fetch native balance |

> 🚫 Do not pass the full `IWalletAccount` into this function — only `MinimalWalletInput` is required and safer.

**📦 Returns**

```
'Balance (in decimal format)'
```

**Native Balance**

```
native = await sdk.crypto.get_balance({"wallet": wallet, "payload": {}})
```

**Token Balance**

```
token = await sdk.crypto.get_balance({
    "wallet": wallet,
    "payload": {"token": "0xTokenAddress"}
})
```

***

### 🔁 Token Swap

#### 🔍 Get Swap Route

Fetch a possible token swap route across chains.

**📥 Parameters**

| Field     | Type                              | Description                                   |
| --------- | --------------------------------- | --------------------------------------------- |
| `wallet`  | `Pick<IWalletAccount, 'account'>` | Wallet account info                           |
| `payload` | `object`                          | Swap details including amount, from/to tokens |

> 🚫 Do not pass the full `IWalletAccount` into this function — only `MinimalWalletInput` is required and safer.

**`payload` structure:**

```
{
  amount: str; // in smallest unit (e.g. wei)
  from: {
    tokenAddress: str;
    chainType: ChainType;
    chainId: Optional(int);
  };
  to: {
    tokenAddress: str;
    chainType: ChainType;
    chainId: Optional(int);
  };
}
```

**📦 Returns**

```
class RouteOutput(TypeDict):
  id: str
  fromChainId: int
  fromAmountUSD: str
  fromAmount: str
  fromToken: TokenWithPrice
  fromAddress: Optional(str)
  toChainId: int
  toAmountUSD: str
  toAmount: str
  toAmountMin: str
  toToken: TokenWithPrice
  toAddress: Optional(str)
  confirmationCode: str
```

**📘 Example**

```
route = await sdk.crypto.get_swap_route({
    "wallet": {"account": 0},
    "payload": {
        "amount": "1000000000000000000",
        "from": {
            "tokenAddress": "0x...",
            "chainType": "ETHEREUM"
        },
        "to": {
            "tokenAddress": "0x...",
            "chainType": "ETHEREUM"
        }
    }
})
```

#### 🔄 Execute Swap

Execute the swap route using a confirmation code.

**📥 Parameters**

| Field     | Type                                           | Description                               |
| --------- | ---------------------------------------------- | ----------------------------------------- |
| `wallet`  | `Pick<IWalletAccount, 'account', 'chainType'>` | Wallet info                               |
| `payload` | `object`                                       | Swap payload including `confirmationCode` |

> 🚫 Do not pass the full `IWalletAccount` into this function — only `MinimalWalletInput` is required and safer.

**`payload` structure:**

```
{
  confirmationCode: str; # from getSwapRoute()
}
```

**📦 Returns**

```
class RouteExecutedResponse(TypeDict):
  transactionStatus: str
  transactionHash: Optional(str)
  fees: Optional(str)
  error: Optional(str)
```

**📘 Example**

```
result = await sdk.crypto.swap({
    "wallet": {"account": 0, "chainType": "ETHEREUM"},
    "payload": {"confirmationCode": "abc123"}
})
```

***
