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

# Integrate Custodial Wallets (Asset Wallets)

<Tip>
  Try [Cobo WaaS Skill](/developers/v2/guides/overview/cobo-waas-skill) in your AI coding assistant (Claude Code, Cursor, etc.). Describe your needs in natural language to auto-generate production-ready SDK code and debug faster 🚀
</Tip>

After you have familiarized yourself with Custodial Wallets through the [Cobo Portal quick start guide](https://manuals.cobo.com/en/portal/quick-start-guide-custodial-wallets), this guide will help you seamlessly integrate Custodial Wallet (Asset Wallets) functionality into your application using the WaaS 2.0 API.

Following this guide, you'll learn how to:

1. Create a wallet
2. Generate a deposit address within the wallet
3. Deposit tokens into the wallet and track the transaction status
4. Withdraw tokens from the wallet
5. Query wallet balances
6. Automatically sweep funds to a designated address

<Note>This guide uses the [development environment](/developers/v2/guides/overview/environments) in all its code samples. It is recommended that you use the development environment to test your new features first before deploying them to the production environment. </Note>

## Prerequisites

* Follow the instructions in [Send your first request](/developers/v2/guides/get-started/get-started-with-waas) to set up your account and send your first API request to the WaaS 2.0 service.
* If you choose to use a WaaS SDK instead of manually writing the API requests, refer to the SDK guide corresponding to the programming language of your choice ([Python](/developers/v2/developer-tools/quickstart-python), [Java](/developers/v2/developer-tools/quickstart-java), [Go](/developers/v2/developer-tools/quickstart-go), [JavaScript](/developers/v2/developer-tools/quickstart-javascript)) to integrate the SDK into your project.

## 1. Create a wallet

To create an Asset Wallet, call the [Create wallet](/developers/v2/api-references/wallets/create-wallet) operation and specify the properties in the request body as follows:

* `wallet_type`: `Custodial`.
* `wallet_subtype`: `Asset`.

Upon successful completion of the request, the response will include the wallet ID, which is the unique identifier of the wallet you have just created. Store this wallet ID as you will need it for subsequent steps.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json

  import cobo_waas2
  from cobo_waas2 import (
     WalletType,
     WalletSubtype,
     CreateCustodialWalletParams,
     CreateWalletParams,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     wallet_api_instance = cobo_waas2.WalletsApi(api_client)
     try:
         # Create an Asset Wallet
         api_response = wallet_api_instance.create_wallet(
             CreateWalletParams(
                 actual_instance=CreateCustodialWalletParams(
                     name="Asset Example Wallet Demo(Python)",
                     wallet_type=WalletType.CUSTODIAL,
                     wallet_subtype=WalletSubtype.ASSET,
                 )
             )
         )
         print("The response of WalletsApi->create_wallet:")
         print(json.dumps(api_response.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling WalletsApi->create_wallet, %s\n", e)

  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.WalletsApi;
  import com.cobo.waas2.model.*;

  public class CreateWalletExample {
     public static void main(String[] args) {
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // Use the development environment
         defaultClient.setEnv(Env.DEV);
         // Replace `<YOUR_API_SECRET>` with your API secret
         defaultClient.setPrivKey("<YOUR_API_SECRET>");
         WalletsApi apiInstance = new WalletsApi();
         try {
             CreateCustodialWalletParams params = new CreateCustodialWalletParams()
                     .name("Asset Example Wallet Demo(Java)")
                     .walletType(WalletType.CUSTODIAL)
                     .walletSubtype(WalletSubtype.ASSET);
             // Create an Asset Wallet
             CreatedWalletInfo result = apiInstance.createWallet(new CreateWalletParams(params));
             System.out.println(result);
         } catch (ApiException e) {
             System.err.println("Exception when calling WalletsApi#createWallet");
             System.err.println("Status code: " + e.getCode());
             System.err.println("Reason: " + e.getResponseBody());
             System.err.println("Response headers: " + e.getResponseHeaders());
             e.printStackTrace();
         }
     }
  }
  ```
</Accordion>

## 2. Generate deposit addresses

After setting up a wallet, you now need to generate deposit addresses within the wallet to receive tokens. To generate deposit addresses within the Asset Wallet you have just created, call the [Create addresses in wallet](/developers/v2/api-references/wallets/create-addresses-in-wallet) operation and specify the parameters and properties as follows:

* Path:
  * `wallet_id`: The ID of the wallet you have just created.
* Request body:
  * `chain_id`: The ID of the blockchain.
  * `count`: Use this parameter to specify the number of addresses you want to create.

Upon successful completion of the request, the response will include the addresses you have just created. You can now proceed to deposit tokens into these addresses.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json

  import cobo_waas2
  from cobo_waas2 import (
     CreateAddressRequest,
     AddressEncoding,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     wallet_api_instance = cobo_waas2.WalletsApi(api_client)
     try:
         # Generate two addresses on the Bitcoin testnet3 (XTN) chain using P2TR encoding
         api_response = wallet_api_instance.create_address(
             wallet_id="<Your Wallet ID>",
             create_address_request=CreateAddressRequest(
                 chain_id="XTN", count=2, encoding=AddressEncoding.ENCODING_P2_TR
             ),
         )
         print("The response of WalletsApi->create_address:")
         for address_info in api_response:
             print(json.dumps(address_info.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling WalletsApi->create_address, %s\n", e)
  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.WalletsApi;
  import com.cobo.waas2.model.AddressEncoding;
  import com.cobo.waas2.model.AddressInfo;
  import com.cobo.waas2.model.CreateAddressRequest;

  import java.util.List;
  import java.util.UUID;

  public class CreateAddressExample {
     public static void main(String[] args) {
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // Use the development environment
         defaultClient.setEnv(Env.DEV);
         // Replace `<YOUR_API_SECRET>` with your API secret
         defaultClient.setPrivKey("<YOUR_API_SECRET>");
         WalletsApi apiInstance = new WalletsApi();
         try {
             UUID wallet_id = UUID.fromString("<YOUR_WALLET_ID>");
             CreateAddressRequest params = new CreateAddressRequest()
                     .chainId("XTN")
                     .count(2)
                     .encoding(AddressEncoding.BECH32);
             // Generate two addresses on the Bitcoin testnet3 (XTN) chain using P2TR encoding
             List<AddressInfo> result = apiInstance.createAddress(wallet_id, params);
             for (AddressInfo addressInfo : result)
                 System.out.println(addressInfo);
         } catch (ApiException e) {
             System.err.println("Exception when calling WalletsApi#createAddress");
             System.err.println("Status code: " + e.getCode());
             System.err.println("Reason: " + e.getResponseBody());
             System.err.println("Response headers: " + e.getResponseHeaders());
             e.printStackTrace();
         }
     }
  }
  ```
</Accordion>

## 3. Process deposit

After depositing tokens to the addresses you have generated, you can track the status of your deposit using one of the following two options. Compared with using API to query the transaction status, webhooks can give you real-time notifications and are thus the recommended option.

### Option 1: Use webhooks for real-time notifications

Webhook is an essential mechanism for the WaaS service to communicate with your application. After you register a webhook endpoint on Cobo Portal, the WaaS service sends push messages to the designated URL when an event occurs.

To learn how to set up a webhook endpoint and register it on Cobo Portal, refer to [Introduction to webhooks and callbacks](/developers/v2/guides/webhooks-callbacks/introduction).

To track the status of your deposit, you can subscribe to the following webhook event types:

* wallets.transaction.created
* wallets.transaction.updated
* wallets.transaction.succeeded
* wallets.transaction.failed

To learn the trigger condition and data structure of each event type, refer to [Webhook event types and data types](/developers/v2/guides/webhooks-callbacks/webhook-event-type).

### Option 2: Get transaction status by API call

To query the status of a deposit transaction, call the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation and set the query parameters as follows:

* `types`: `Deposit`.
* `statuses`: `Confirming,Completed`. If you are depositing from an external address, you will be able to query the transaction details when the transaction is waiting for the required number of confirmations or when it is successfully completed.
* `wallet_ids`: The ID of the wallet you have created in the first step.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json
  import uuid

  import cobo_waas2
  from cobo_waas2 import (
     CreateAddressRequest,
     AddressEncoding,
     TransferParams,
     TransferSource,
     CustodialTransferSource,
     WalletSubtype,
     TransferDestination, AddressTransferDestination, TransferDestinationType, AddressTransferDestinationAccountOutput,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     transaction_api_instance = cobo_waas2.TransactionsApi(api_client)
     try:
         # List deposit transactions
         api_response = transaction_api_instance.list_transactions(
             types="Deposit",
             statuses="Confirming,Completed",
             wallet_ids="<YOUR_WALLET_ID>"
         )
         print("The response of TransactionsApi->list_transactions:")
         print(json.dumps(api_response.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling TransactionsApi->list_transactions, %s\n", e)
  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.TransactionsApi;
  import com.cobo.waas2.model.ListTransactions200Response;

  import java.util.UUID;

  public class ListTransactionsExample {
     public static void main(String[] args) {
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // Use the development environment
         defaultClient.setEnv(Env.DEV);
         // Replace `<YOUR_API_SECRET>` with your API secret
         defaultClient.setPrivKey("<YOUR_API_SECRET>");
         TransactionsApi apiInstance = new TransactionsApi();
         try {
             String requestId = null;
             String coboIds = null;
             String transactionIds = null;
             String transactionHashes = "";
             String types = "Deposit";
             String statuses = "Confirming,Completed";
             String walletIds = "<YOUR_WALLET_ID>";
             String chainIds = null;
             String tokenIds = null;
             String assetIds = null;
             UUID vaultId = null;
             UUID projectId = null;
             Long minCreatedTimestamp = null;
             Long maxCreatedTimestamp = null;
             Integer limit = 50;
             String before = null;
             String after = null;

             // List deposit transactions
             ListTransactions200Response result = apiInstance.listTransactions(
                     requestId, coboIds, transactionIds, transactionHashes, types, statuses, walletIds, chainIds,
                     tokenIds, assetIds, vaultId, projectId, minCreatedTimestamp, maxCreatedTimestamp, limit, before, after);
             System.out.println(result);
         } catch (ApiException e) {
             System.err.println("Exception when calling WalletsApi#createAddress");
             System.err.println("Status code: " + e.getCode());
             System.err.println("Reason: " + e.getResponseBody());
             System.err.println("Response headers: " + e.getResponseHeaders());
             e.printStackTrace();
         }
     }
  }
  ```
</Accordion>

## Deposit prerequisites

Before you deposit tokens, make sure the chain is activated for your organization and the token is listed and enabled for deposits. A token accepts deposits only when its `can_deposit` property is `true`. Deposits made to a token that is not enabled (`can_deposit` is `false`, meaning deposits are currently suspended) may not be detected or credited automatically, so confirm this property before you send funds.

**Check whether a token accepts deposits**

Call the [List supported tokens](/developers/v2/api-references/wallets/list-supported-tokens) operation and set the query parameter `token_ids` to the token you want to check (for example, `ETH_USDT`). In the response, read the `can_deposit` field of the token:

* `true`: Deposits are enabled. You can deposit to this token.
* `false`: Deposits are currently suspended. Do not send funds.

To check a single token, you can also call [Get token information](/developers/v2/api-references/wallets/get-token-information) with the `token_id` path parameter. Both operations accept the optional query parameters `wallet_type`, `wallet_subtype`, and `chain_ids` to narrow the results.

**Check the status of a deposit you already sent**

If you have already sent a deposit to a token that was not enabled at the time, do not send further funds to the same address. Instead, confirm the current status of the transfer by calling the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation with the following query parameters:

* `types`: `Deposit`.
* `token_ids`: The token you deposited, for example `ETH_USDT`.
* `wallet_ids`: The ID of your wallet.
* `transaction_hash` (optional): The on-chain transaction hash, to locate a specific transfer.

Read the `status` field of each returned transaction to determine whether the deposit has been recorded. For sample code that calls this operation, see [Option 2: Get transaction status by API call](#option-2-get-transaction-status-by-api-call).

## Memo and tag requirements

Some chains require a memo or tag in addition to the deposit address so that the deposit can be routed to the correct account, such as XRP, XLM, EOS, ATOM, TON, IOST, BNB Chain, and Hedera. A deposit sent to one of these chains without the required memo or tag, or with an incorrect memo or tag, will fail to match the deposit address and will not be credited automatically. If a deposit on a memo-required chain does not appear in your transaction list, contact [help@cobo.com](mailto:help@cobo.com) for assistance.

**Check whether a chain requires a memo or tag**

Call the [List supported chains](/developers/v2/api-references/wallets/list-supported-chains) operation (or [List enabled chains](/developers/v2/api-references/wallets/list-enabled-chains) for the chains enabled for your organization) and read the `require_memo` field of the chain:

* `true`: The chain requires a memo or tag for every deposit.
* `false`: No memo or tag is required.

To check a single chain, call [Get chain information](/developers/v2/api-references/wallets/get-chain-information) with the `chain_id` path parameter.

**Get the memo or tag for a deposit address**

The memo or tag is bound to the deposit address. When you generate an address on a memo-required chain, the address response includes a `memo` field. Retrieve it from the response of [Create addresses in wallet](/developers/v2/api-references/wallets/create-addresses-in-wallet), or look it up later with [List wallet addresses](/developers/v2/api-references/wallets/list-wallet-addresses). When you deposit, provide both the address and its `memo` value from this response, and include the exact memo or tag with every transfer.

**Confirm a deposit on a memo-required chain**

To check whether a deposit to a memo-required chain has been credited, call the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation with `types` set to `Deposit` and `wallet_ids` set to your wallet ID, then read the `status` field of each returned transaction.

## Internal and contract-triggered transactions

The deposit detection mechanism tracks standard top-level transfers to your deposit addresses. Transfers that are not top-level — such as internal (trace) transfers produced by a contract call, or token movements emitted by a smart contract rather than sent directly to your address — may not be detected or credited automatically. This applies to several chains.

If you expect a deposit from this type of transfer and it does not appear, first verify that the transaction was completed on-chain using the relevant blockchain explorer, then use the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation to check whether it has been recorded by Cobo. If no record is found, contact [help@cobo.com](mailto:help@cobo.com) for assistance.

## Deposit troubleshooting

### How do I re-check a deposit if I missed its webhook notification?

Webhook notifications can be missed if your endpoint was temporarily unavailable. You do not need to wait for a new notification to confirm a deposit. Query the current state directly with the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation, or retrieve a single transfer with the [Get transaction information](/developers/v2/api-references/transactions/get-transaction-information) operation. Make sure your webhook endpoint returns a success status code so that future events are delivered reliably; see [Introduction to webhooks and callbacks](/developers/v2/guides/webhooks-callbacks/introduction).

### What happens to deposits made before a token is listed?

Deposits sent before a token is listed and enabled for deposits may not be detected or credited at the time of the transfer. Before depositing, confirm that the token is enabled as described in [Deposit prerequisites](#deposit-prerequisites). To check whether such a deposit has since been recorded, use the [List all transactions](/developers/v2/api-references/transactions/list-all-transactions) operation. If the transaction does not appear, there is no automatic recovery for pre-listing deposits. Contact [help@cobo.com](mailto:help@cobo.com) for assistance.

## 4. Withdraw tokens

Now that you have tokens in your wallet, it's time to try withdrawing them.

### Set up a callback endpoint

To enhance the security of your transactions, it is highly recommended that you set up a callback endpoint to receive and approve withdrawal requests. Once you initiate a withdrawal using the WaaS 2.0 API, the callback endpoint will receive a callback message containing the transaction details. The transaction will proceed only if you approve the withdrawal request.

To learn how to set up a callback endpoint and register it on Cobo Portal, refer to [Introduction to webhooks and callbacks](/developers/v2/guides/webhooks-callbacks/introduction).

### Withdraw tokens

To withdraw tokens from the Asset Wallet, call the [Transfer token](/developers/v2/api-references/transactions/transfer-token) operation and set the properties in the request body as follows:

* `request_id`: Your request ID.
* `source.source_type`: `Asset`.
* `source.wallet_id`: The ID of the wallet you have just created.
* `token_id`: The ID of the token you want to withdraw.
* `destination.destination_type`: `Address`.
* `destination.account_output`: The receiving address and memo (if applicable), and the amount you want to withdraw.
* `category_names`: The custom category for you to identify your transactions.
* `description`: The description of the transfer.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json
  import uuid

  import cobo_waas2
  from cobo_waas2 import (
     CreateAddressRequest,
     AddressEncoding,
     TransferParams,
     TransferSource,
     CustodialTransferSource,
     WalletSubtype,
     TransferDestination, AddressTransferDestination, TransferDestinationType, AddressTransferDestinationAccountOutput,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     transaction_api_instance = cobo_waas2.TransactionsApi(api_client)
     try:
         # Transfer Bitcoin testnet3(XTN) token from the wallet
         api_response = transaction_api_instance.create_transfer_transaction(
             transfer_params=TransferParams(
                 request_id=str(uuid.uuid4()),
                 source=TransferSource(
                     actual_instance=CustodialTransferSource(
                         source_type=WalletSubtype.ASSET,
                         wallet_id="<YOUR_WALLET ID>",
                     )
                 ),
                 token_id="XTN",
                 destination=TransferDestination(
                     actual_instance=AddressTransferDestination(
                         destination_type=TransferDestinationType.ADDRESS,
                         account_output=AddressTransferDestinationAccountOutput(
                             address="<TARGET_ADDRESS>",
                             amount="<TRANSFER_AMOUNT>"
                         )
                     )
                 ),
                 category_names=["<CATEGORY_NAME>"],
                 description="<DESCRIPTION>",
             )
         )
         print("The response of TransactionsApi->create_transfer_transaction:")
         print(json.dumps(api_response.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling TransactionsApi->create_transfer_transaction, %s\n", e)
  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.TransactionsApi;
  import com.cobo.waas2.model.*;

  import java.util.ArrayList;
  import java.util.List;
  import java.util.UUID;

  public class TransferExample {
     public static void main(String[] args) {
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // Use the development environment
         defaultClient.setEnv(Env.DEV);
         // Replace `<YOUR_API_SECRET>` with your API secret
         defaultClient.setPrivKey("<YOUR_API_SECRET>");
         TransactionsApi apiInstance = new TransactionsApi();
         try {
             UUID walletId = UUID.fromString("<YOUR_WALLET_ID>");

             TransferParams params = new TransferParams();
             params.setRequestId("Demo" + UUID.randomUUID());

             CustodialTransferSource custodialTransferSource = new CustodialTransferSource().sourceType(WalletSubtype.ASSET).walletId(walletId
  );
             params.setSource(new TransferSource(custodialTransferSource));

             params.setTokenId("XTN");
             AddressTransferDestination addressTransferDestination = new AddressTransferDestination()
                     .destinationType(TransferDestinationType.ADDRESS)
                     .accountOutput(new AddressTransferDestinationAccountOutput()
                             .address("<TARGET_ADDRESS>")
                             .amount("<TRANSFER_AMOUNT>"));
             params.setDestination(new TransferDestination(addressTransferDestination));

             List<String> categoryNames = new ArrayList<>();
             categoryNames.add("<CATEGORY_NAME>");
             params.categoryNames(categoryNames).description("<DESCRIPTION>");

             // Transfer Bitcoin testnet3(XTN) token from the wallet
             CreateTransferTransaction201Response result = apiInstance.createTransferTransaction(params);
             System.out.println(result);
         } catch (ApiException e) {
             System.err.println("Exception when calling TransactionsApi#createTransferTransaction");
             System.err.println("Status code: " + e.getCode());
             System.err.println("Reason: " + e.getResponseBody());
             System.err.println("Response headers: " + e.getResponseHeaders());
             e.printStackTrace();
         }
     }
  }
  ```
</Accordion>

The response of the withdrawal request is as follows. Record the transaction ID as you will use it in the following steps.

```json theme={null}
{
   "request_id": "<YOUR_REQUEST_ID>",
   "transaction_id": "<THE_GENERATED_TRANSACTION_ID>",
   "status": "Submitted"
}
```

### Confirm the withdrawal

If you have set up a callback endpoint, after you initiate the withdrawal transaction, your callback endpoint will receive a message containing the transaction details. Check if the transaction meets expectations, and respond with a success status code (200 or 201) and a response body of `ok` to approve the transaction. To learn more about handling a callback message, see [Set up a callback or webhook endpoint](/developers/v2/guides/webhooks-callbacks/set-up-endpoint).

### Monitor the withdrawal status

In addition to webhook events, you can also call the [Get transaction information](/developers/v2/api-references/transactions/get-transaction-information) operation to query the status of the transaction. Set the path parameter `transaction_id` to the transaction ID returned in the response of the previous withdrawal request.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json
  import uuid

  import cobo_waas2
  from cobo_waas2 import (
     CreateAddressRequest,
     AddressEncoding,
     TransferParams,
     TransferSource,
     CustodialTransferSource,
     WalletSubtype,
     TransferDestination, AddressTransferDestination, TransferDestinationType, AddressTransferDestinationAccountOutput,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     transaction_api_instance = cobo_waas2.TransactionsApi(api_client)
     try:
         # Get transaction by ID
         api_response = transaction_api_instance.get_transaction_by_id(
             transaction_id="<YOUR_TRANSACTION_ID>"
         )
         print("The response of TransactionsApi->get_transaction_by_id:")
         print(json.dumps(api_response.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling TransactionsApi->get_transaction_by_id, %s\n", e)
  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.TransactionsApi;
  import com.cobo.waas2.model.TransactionDetail;

  import java.util.UUID;

  public class GetTransactionExample {
     public static void main(String[] args) {
         ApiClient defaultClient = Configuration.getDefaultApiClient();
         // Use the development environment
         defaultClient.setEnv(Env.DEV);
         // Replace `<YOUR_API_SECRET>` with your API secret
         defaultClient.setPrivKey("<YOUR_API_SECRET>");
         TransactionsApi apiInstance = new TransactionsApi();
         try {
             UUID transactionId = UUID.fromString("<YOUR_TRANSACTION_ID>");
             
             // Get transaction by ID
             TransactionDetail result = apiInstance.getTransactionById(transactionId);
             System.out.println(result);
         } catch (ApiException e) {
             System.err.println("Exception when calling TransactionsApi#getTransactionById");
             System.err.println("Status code: " + e.getCode());
             System.err.println("Reason: " + e.getResponseBody());
             System.err.println("Response headers: " + e.getResponseHeaders());
             e.printStackTrace();
         }
     }
  }
  ```
</Accordion>

## 5. Query wallet balances

After successfully withdrawing tokens from your wallet, you can call [List token balances by wallet](/developers/v2/api-references/wallets/list-token-balances-by-wallet) to query the wallet balances. Specify the path and query parameters as follows:

* `wallet_id`: The ID of the wallet you have just created.
* `token_ids`: You can leave it empty to query the balances of all tokens, or set it to the specific token you want to query.

<Accordion title="Sample code in Python">
  ```python theme={null}
  import json

  import cobo_waas2
  from cobo_waas2 import (
     WalletType,
     WalletSubtype,
  )

  configuration = cobo_waas2.Configuration(
     # Replace `<YOUR_API_SECRET>` with your API secret
     api_private_key="<YOUR_API_SECRET>",
     # Use the development environment
     host="https://api.dev.cobo.com/v2"
  )

  # Enter a context with an instance of the API client
  with cobo_waas2.ApiClient(configuration) as api_client:
     # Create an instance of the API class
     wallet_api_instance = cobo_waas2.WalletsApi(api_client)
     try:
         # Query token balances
         api_response = wallet_api_instance.list_token_balances_for_wallet(
             wallet_id="<YOUR_WALLET_ID>",
         )
         print(f"The response of WalletsApi->list_token_balances_for_wallet:")
         print(json.dumps(api_response.to_dict(), indent=2))

     except Exception as e:
         print("Exception when calling WalletsApi->list_token_balances_for_wallet, %s\n", e)
  ```
</Accordion>

<Accordion title="Sample code in Java">
  ```java theme={null}
  import com.cobo.waas2.ApiClient;
  import com.cobo.waas2.ApiException;
  import com.cobo.waas2.Configuration;
  import com.cobo.waas2.Env;
  import com.cobo.waas2.api.WalletsApi;
  import com.cobo.waas2.model.ListTokenBalancesForAddress200Response;

  import java.util.UUID;

  public class ListTokenBalancesExample {
      public static void main(String[] args) {
          ApiClient defaultClient = Configuration.getDefaultApiClient();
          // Use the development environment
          defaultClient.setEnv(Env.DEV);
          // Replace `<YOUR_API_SECRET>` with your API secret
          defaultClient.setPrivKey("<YOUR_API_SECRET>");
          WalletsApi apiInstance = new WalletsApi();
          try {
              UUID wallet_id = UUID.fromString("<YOUR_WALLET_ID>");
              String tokenIds = null;
              Integer limit = 50;
              String before = null;
              String after = null;
              // Query token balances
              ListTokenBalancesForAddress200Response result = apiInstance.listTokenBalancesForWallet(wallet_id, tokenIds, limit, before, after);
              System.out.println(result);
          } catch (ApiException e) {
              System.err.println("Exception when calling WalletsApi#listTokenBalancesForWallet");
              System.err.println("Status code: " + e.getCode());
              System.err.println("Reason: " + e.getResponseBody());
              System.err.println("Response headers: " + e.getResponseHeaders());
              e.printStackTrace();
          }
      }
  }
  ```
</Accordion>

## 6. Sweep funds automatically (auto-sweep)

Auto-sweep automatically consolidates tokens from your deposit addresses into a designated sweep-to address, so that you do not need to move funds out of each deposit address manually. To create an auto-sweep task, call the [Create auto-sweep task](/developers/v2/api-references/autosweep/create-auto-sweep-task) operation and specify the following:

* `wallet_id`: The ID of the wallet you created.
* `token_id`: The ID of the token to sweep.
* `min_balance_threshold`: (Optional) The minimum token balance an address must hold to be swept. Addresses holding less than this value are skipped, which lets you filter out dust. There is no per-address blocklist; use `min_balance_threshold` to control the minimum sweep amount.

<Note>
  A sweep moves tokens out of a deposit address, which requires native chain coin to pay for gas. Make sure that gas is available either in the source deposit address or through a configured Fee Station or Auto Fueling. Reaching the deposit threshold alone does not complete a sweep: if no gas is available, the sweep cannot be broadcast. When a sweep cannot proceed, the reason is reported in the `failed_reasons` array returned by the task details.
</Note>

### Retrieve the swept transactions

The Create auto-sweep task operation returns immediately with a `task_id`. At this point the task `status` is `Submitted` and the `transaction_ids` array is empty. This is expected and does not indicate a failure.

The task transitions to `TransactionCreated` once it triggers one or more sweep transactions, at which point `transaction_ids` is populated. To retrieve the transaction IDs, poll the [Get auto-sweep task details](/developers/v2/api-references/autosweep/get-auto-sweep-task-details) operation with your `task_id` until `status` becomes `TransactionCreated`.

### Timing and lifecycle

Auto-sweep is poll-based rather than instant. A sweep is initiated shortly after its trigger condition is met, so a short delay between the deposit and the sweep transaction is normal. Tasks that cannot proceed do not stay pending indefinitely: a task that remains without gas or without a signature is automatically cancelled after a timeout, and the affected funds remain in the source address so that you can sweep them again later.

<Info>For EVM-compatible chains (such as Ethereum and BNB Smart Chain), the same address is used across all EVM chains. As a result, when you list sweep-to addresses with [List sweep-to addresses](/developers/v2/api-references/autosweep/list-sweep-to-addresses), only one address entry (shown under Ethereum) is returned for all EVM-compatible chains. Do not expect a separate entry for each EVM chain.</Info>
