Skip to main content
即刻安装 Cobo WaaS Skill,在 Claude Code、Cursor 等 AI 开发环境中使用自然语言集成 WaaS API,显著提升开发效率 🚀
本指南将帮助您开始使用智能合约钱包 (Safe{Wallet})。通过本指南,您将能够使用 WaaS 2.0 API:
  1. 查询您可以使用的链和代币
  2. 设置 Safe{Wallet} 并配置交易风控
  3. 存入和提取代币
  4. 调用智能合约
本指南在所有代码示例中使用开发环境。建议您首先使用开发环境测试新功能,然后再将其部署到生产环境。

前提条件

在设置 Safe{Wallet} 之前,您必须执行以下步骤: 使用 WaaS API 时,请确保以下几点:
  • 按照开始使用 WaaS 2.0中的说明设置您的帐户并向 WaaS 2.0 服务发送您的第一个 API 请求。
  • 如果您选择使用 WaaS SDK 而不是手动编写 API 请求,请参考与您选择的编程语言相对应的 SDK 指南(PythonJavaGoJavaScript)将 SDK 集成到您的项目中。
  • 准备一些测试代币,因为在测试充币功能时您将需要它们。要了解您可以使用哪些测试代币,请参阅查询链和代币信息。在大多数情况下,您可以使用 XTN 作为测试代币。
  • 强烈建议您设置一个回调端点以接收和批准提币请求,并设置一个 webhook 端点以接收有关交易状态更新和您关心的其他事件的实时通知。要了解如何设置和注册 webhook 和回调端点,请参阅Webhook 和回调简介

1. 查询启用的链

在开始设置您的钱包和生成充币地址之前,了解您可以使用哪些链和代币非常重要。要检索 Safe{Wallet} 可用的链及其对应的链 ID,请调用List enabled chains并指定以下查询参数:
  • wallet_typeSmartContract
  • wallet_subtypeSafe{Wallet}
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 enabled chains
       api_response = wallet_api_instance.list_enabled_chains(
           wallet_type=WalletType.SMARTCONTRACT,
           wallet_subtype=WalletSubtype.SAFE_WALLET
       )
       print(f"The response of WalletsApi->list_enabled_chains:")
       print(json.dumps(api_response.to_dict(), indent=2))

   except Exception as e:
       print("Exception when calling WalletsApi->list_enabled_chains, %s\n", e)
如果您想使用不在列表中的链,您需要先在 Cobo Portal 上启用该链。要了解如何启用链,请参阅转账(充币/提币) 如果您已经达到可用链的数量限制,请考虑升级您的定价计划

2. 查询启用的代币

要检索 Safe{Wallet} 可用的代币及其对应的代币 ID,请调用List enabled tokens并指定以下查询参数:
  • wallet_typeSmartContract
  • wallet_subtypeSafe{Wallet}
  • chain_ids:指定您选择的链。您也可以留空此参数以查询所有链上的启用代币。
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 enabled tokens
       api_response = wallet_api_instance.list_enabled_tokens(
           wallet_type=WalletType.SMARTCONTRACT,
           wallet_subtype=WalletSubtype.SAFE_WALLET
       )
       print(f"The response of WalletsApi->list_enabled_tokens:")
       print(json.dumps(api_response.to_dict(), indent=2))

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

3. 设置钱包

在 Cobo Portal 上设置 Safe{Wallet},按照以下步骤操作:
  1. 如果您已经有一个 Safe{Wallet},您可以将其导入 Cobo Portal。您也可以直接在 Cobo Portal 上创建 Safe{Wallet}
  2. 为您的 Safe{Wallet} 设置委托密钥

4. 配置链上交易风控

为了允许委托执行单签操作,您必须在 Cobo Portal 上设置链上交易风控,以自动批准由委托发起的某些交易。在本指南中,我们将使用您在前提条件部分中准备的 MPC 钱包地址作为委托。
  1. 配置策略以自动批准通过 MPC 钱包发起的代币提币和合约调用。请参阅提供的截图作为示例。
设置链上风险策略
  1. 需要 Safe 签署者的多重签名确认。点击 提交 以发起多重签名交易。

5. 存入代币

按照存入资产中的说明将代币存入您的 Safe{Wallet}。 在存入代币到您生成的地址后,您可以通过以下两种方式之一跟踪充币状态。与使用 API 查询交易状态相比,Webhook 可以提供实时通知,因此是推荐的方式。

选项 1:使用 Webhook 实时通知

Webhook 是 WaaS 服务与您的 App 通信的重要机制。注册 Webhook 端点后,WaaS 服务会在事件发生时向指定 URL 发送推送消息。 要了解如何设置 Webhook 端点并在 Cobo Portal 上注册,请参阅Webhook 和回调简介 要跟踪充币状态,您可以订阅以下 Webhook 事件类型:
  • wallets.transaction.created
  • wallets.transaction.updated
  • wallets.transaction.succeeded
  • wallets.transaction.failed
要了解每个事件类型的触发条件和数据结构,请参阅Webhook 事件类型和数据类型

选项 2:通过 API 调用获取交易状态

要查询充币交易的状态,请调用List all transactions并设置以下查询参数:
  • typesDeposit
  • statusesConfirming, Completed。如果您从外部地址充币,您将能够在交易等待所需数量的确认或成功执行时查询交易详细信息。
  • wallet_ids:您在第一步中创建的钱包 ID。您可以从 Cobo Portal 上的钱包列表中获取钱包 ID。
import json
import uuid


import cobo_waas2
from cobo_waas2 import (
   CreateAddressRequest,
   AddressEncoding,
   TransferParams,
   TransferSource,
   MpcTransferSource,
   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)

6. 提取代币

现在您已经有了代币,可以尝试提取它们。

设置回调端点

为了增强交易的安全性,强烈建议您设置回调端点以接收和批准提币请求。一旦您使用 WaaS 2.0 API 发起提币,回调端点将接收包含交易详细信息的回调消息。只有当您批准提币请求时,交易才会继续。 要了解如何设置回调端点并在 Cobo Portal 上注册,请参阅Webhook 和回调简介

提取代币

  1. 要从您的 Safe{Wallet} 提取代币,请首先从 Cobo Portal 获取其钱包 ID。将鼠标悬停在钱包列表中的钱包上,复制钱包 ID,并保存以备后用。
  2. 调用List Delegates以检索可用的委托。指定以下参数和属性:
    • Path:
      • wallet_id:您的 Safe{Wallet} 的钱包 ID。
    • Request body:
      • request_typeTransfer
  3. 调用转账代币以使用委托发起提币。在请求包体中指定属性如下:
    • request_id:使用唯一 ID 跟踪交易请求。
    • source
      • source_typeSafe{Wallet}
      • wallet_id:您的 Safe{Wallet} 的钱包 ID。
      • address:您的 Safe{Wallet} 的地址。您可以调用获取钱包信息操作以检索地址。
      • delegate:委托的信息。您可以调用List Delegates操作以检索可用的委托。
    • token_id:代币 ID。
    • destination
      • destination_typeAddress
      • account_output
        • address:接收地址。
        • memo:备注(如果适用)。
        • amount:转账金额。
    • category_names:用于识别交易的自定义类别。
    • description:转账的描述。
import json
import uuid

import cobo_waas2

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"
)

def get_delegate(wallet_id, request: cobo_waas2.SafeWalletDelegates):
# 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.WalletsSmartContractWalletsApi(api_client)
        try:
            # Call the List Delegates operation to retrieve available Delegates
            api_response = wallet_api_instance.list_safe_wallet_delegates(
                wallet_id=wallet_id,
                safe_wallet_delegates=request
            )
            if not api_response:
                raise Exception("No delegate found")
            print("The response of WalletsApi->list_safe_wallet_delegates:")
            print(json.dumps(api_response[0].to_dict(), indent=2))
            # Return the first Delegate 
            return api_response[0]
        except Exception as e:
            print("Exception when calling WalletsApi: %s\n", e)

def get_wallet(wallet_id) -> cobo_waas2.SafeWallet:
    with cobo_waas2.ApiClient(configuration) as api_client:
        # Create an instance of the API class
        wallet_api_instance = cobo_waas2.WalletsApi(api_client)
        try:
            # Call the Get wallet information operation to retrieve the wallet information, including the wallet address
            api_response = wallet_api_instance.get_wallet_by_id(
                wallet_id=wallet_id
            )
            print("The response of WalletsApi->get_wallet_by_id:")
            print(json.dumps(api_response.to_dict(), indent=2))
            return api_response.actual_instance.actual_instance
        except Exception as e:
            print("Exception when calling WalletsApi: %s\n", e)


token_id = "<TOKEN_ID>"
# Enther the receiving address
receiver_address = "<TARGET_ADDRESS>"
# Enter the wallet ID found on Cobo Portal 
wallet_id = "<YOUR_WALLET_ID>"
# Enter the amount of tokens you want to transfer
amount = "<AMOUNT>"
transfer_request = cobo_waas2.SafeWalletDelegates(
        actual_instance=cobo_waas2.SafeWalletDelegatesTransfer(
            request_type=cobo_waas2.EstimateFeeRequestType.TRANSFER,
            token_id=token_id,
            address=receiver_address,
        )
    )
# Retrieve a list of available Delegates
delegate = get_delegate(wallet_id, transfer_request)
# Retrieve detailed information about the Safe{Wallet}
wallet = get_wallet(wallet_id)

with cobo_waas2.ApiClient(configuration) as api_client:
    # Create an instance of the API class
    wallet_api_instance = cobo_waas2.TransactionsApi(api_client)
    try:
        # Initiate token transfer through a Delegate
        api_response = wallet_api_instance.create_transfer_transaction(
            cobo_waas2.TransferParams(
                request_id=str(uuid.uuid4()),
                # Set the sending address and the Delegate
                source=cobo_waas2.TransferSource(
                    actual_instance=cobo_waas2.SafeTransferSource(
                        source_type=cobo_waas2.WalletSubtype.SAFE_WALLET,
                        wallet_id=wallet_id,
                        address=wallet.safe_address,
                        delegate=delegate,
                    )
                ),
                token_id=token_id,
                # Set the receiving address and withdrawal amount
                destination=cobo_waas2.TransferDestination(
                    actual_instance=cobo_waas2.AddressTransferDestination(
                        destination_type=cobo_waas2.TransferDestinationType.ADDRESS,
                        account_output=cobo_waas2.AddressTransferDestinationAccountOutput(
                            address=receiver_address,
                            amount=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 WalletsApi: %s\n", e)
提币请求的响应如下。记录交易 ID,因为您将在后续步骤中使用它。
{
   "request_id": "<YOUR_REQUEST_ID>",
   "transaction_id": "<THE_GENERATED_TRANSACTION_ID>",
   "status": "Submitted"
}

确认提币

如果您已经设置了回调端点,在发起提币交易后,您的回调端点将接收包含交易详细信息的消息。检查交易是否符合预期,并使用成功状态代码(200 或 201)和响应包体 ok 来批准交易。要了解更多关于处理回调消息的信息,请参阅处理消息

监控提币状态

除了 Webhook 事件外,您还可以调用获取交易信息操作以查询交易状态。将路径参数 transaction_id 设置为前一个提币请求响应中返回的交易 ID。
import json
import uuid


import cobo_waas2
from cobo_waas2 import (
   CreateAddressRequest,
   AddressEncoding,
   TransferParams,
   TransferSource,
   MpcTransferSource,
   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)

7. 调用智能合约

本节介绍如何使用您的 Safe{Wallet} 通过委托调用智能合约。
  1. 从 Cobo Portal 获取您的 Safe{Wallet} 的钱包 ID。将鼠标悬停在钱包列表中的钱包上,复制钱包 ID,并保存以备后用。
  2. 调用List Delegates以检索可用的委托。指定以下参数和属性:
    • Path:
      • wallet_id:您的 Safe{Wallet} 的钱包 ID。
    • Request body:
      • request_typeContractCall
  3. 调用调用智能合约以使用委托调用智能合约。在请求包体中指定属性如下:
    • request_id:使用唯一 ID 跟踪交易请求。
    • chain_id:您的 Safe{Wallet} 运行的链 ID。您可以调用获取钱包信息操作以检索信息。
    • source
      • source_typeSafe{Wallet}
      • wallet_id:您的 Safe{Wallet} 的钱包 ID。
      • address:您的 Safe{Wallet} 的地址。您可以调用获取钱包信息操作以检索信息。
      • delegate:委托的信息。您可以调用List Delegates操作以检索可用的委托。
    • destination
      • destination_typeEVM_Contract
      • address:目的地址。
      • value:转账金额。
      • calldata:交易 calldata。
    • category_names:用于识别交易的自定义类别。
    • description:转账的描述。
import json

import cobo_waas2

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"
)

def get_delegate(wallet_id, request: cobo_waas2.SafeWalletDelegates):
# 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.WalletsSmartContractWalletsApi(api_client)
        try:
            # Call the List Delegates operation to retrieve available Delegates
            api_response = wallet_api_instance.list_safe_wallet_delegates(
                wallet_id=wallet_id,
                safe_wallet_delegates=request
            )
            if not api_response:
                raise Exception("No delegate found")
            print("The response of WalletsApi->list_safe_wallet_delegates:")
            print(json.dumps(api_response[0].to_dict(), indent=2))
            return api_response[0]
        except Exception as e:
            print("Exception when calling WalletsApi: %s\n", e)

def get_wallet(wallet_id) -> cobo_waas2.SafeWallet:
    with cobo_waas2.ApiClient(configuration) as api_client:
        # Create an instance of the API class
        wallet_api_instance = cobo_waas2.WalletsApi(api_client)
        try:
            # Call the Get wallet information operation to retrieve the wallet information, including the wallet address
            api_response = wallet_api_instance.get_wallet_by_id(
                wallet_id=wallet_id
            )
            print("The response of WalletsApi->get_wallet_by_id:")
            print(json.dumps(api_response.to_dict(), indent=2))
            return api_response.actual_instance.actual_instance
        except Exception as e:
            print("Exception when calling WalletsApi: %s\n", e)

# Set the destination address 
contract_address = "<CONTRACT_ADDRESS>"
# Set the transaction calldata
data = "<DATA>"
# Set the transfer amount
value = "<VALUE>"

contract_call_request = cobo_waas2.SafeWalletDelegates(
        actual_instance=cobo_waas2.SafeWalletDelegatesContractCall(
            request_type=cobo_waas2.EstimateFeeRequestType.CONTRACTCALL,
            address=contract_address,
            calldata=data,
            value=value,
        )
    )

# Retrieve a list of available Delegates.
delegate = get_delegate(wallet_id, contract_call_request)
# Retrieve detailed information about the Safe{Wallet}.
wallet = get_wallet(wallet_id)

with cobo_waas2.ApiClient(configuration) as api_client:
    wallet_api_instance = cobo_waas2.TransactionsApi(api_client)
    try:
        # Call the smart contract
        api_response = wallet_api_instance.create_contract_call_transaction(
            cobo_waas2.ContractCallParams(
                request_id=str(uuid.uuid4()),
                chain_id=wallet.chain_id,
                source=cobo_waas2.ContractCallSource(
                    actual_instance=cobo_waas2.SafeContractCallSource(
                        source_type=cobo_waas2.ContractCallSourceType.SAFE_WALLET,
                        wallet_id=wallet_id,
                        address=wallet.safe_address,
                        delegate=delegate,
                    )
                ),
                destination=cobo_waas2.ContractCallDestination(
                    actual_instance=cobo_waas2.EvmContractCallDestination(
                        destination_type=cobo_waas2.ContractCallDestinationType.EVM_CONTRACT,
                        address=contract_address,
                        calldata=data,
                        value=value,
                    ),
                ),
                category_names=["<CATEGORY_NAME>"],
                description="<DESCRIPTION>",
            )
        )
        print("The response of TransactionsApi->create_contract_call_transaction:")
        print(json.dumps(api_response.to_dict(), indent=2))
    except Exception as e:
        print("Exception when calling TransactionsApi: %s\n", e)
合约调用请求的响应如下。您可以使用响应中的交易 ID 来查询交易状态。
{
   "request_id": "<YOUR_REQUEST_ID>",
   "transaction_id": "<THE_GENERATED_TRANSACTION_ID>",
   "status": "Submitted"
}