mcpField
B
bingx-sub-account

bingx-sub-account

github.com/bingx-api其他19170 次安装6 天前更新
代码仓库

关于 bingx-sub-account

用于管理 BingX 子账户主账户操作的 Skill,涵盖账户与 API Key 管理、资产查询和划转,并说明认证请求、参数校验及实盘写操作的确认要求。

主要功能

  1. 01创建和列出子账户
  2. 02冻结或解冻账户
  3. 03管理子账户 API Key
  4. 04查询资产及划转记录
  5. 05授权和划转资产

适用场景

  1. 01开设子账户并创建其 API Key
  2. 02查看多个子账户的余额
  3. 03在账户间划转资产
  4. 04检查充值和划转历史

MCP 相关

该 Skill 指导 Agent 调用经过认证的 BingX 子账户 API,未说明 MCP 服务端或客户端功能。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bingx-api/api-ai-skills --skill bingx-sub-account

安装后在 Claude Code 中输入/bingx-sub-account确认已加载。

附带文件api-reference.md

详细介绍

BingX 子账户管理

用于管理 BingX 子账户(主账户操作)的身份验证端点。所有端点均需要 HMAC SHA256 签名身份验证。多个写入端点要求使用 Content-Type: application/json,而非标准的表单编码——请参阅下方的 快速入门 辅助说明。

基础 URL: 参阅 references/base-urls.md | 身份验证: 参阅 references/authentication.md


快速参考

端点方法描述身份验证请求体类型
/openApi/account/v1/uidGET查询账户 UID是—
/openApi/v1/account/apiPermissionsGET查询 API Key 权限是—
/openApi/v1/account/apiPermissionsGET查询 API Key 限制是—
/openApi/account/v1/apiKey/queryGET查询 API Key 信息(本人或子账户)是—
/openApi/subAccount/v1/createPOST创建子账户是JSON
/openApi/subAccount/v1/listGET列出子账户是—
/openApi/subAccount/v1/assetsGET查询子账户资金资产是—
/openApi/subAccount/v1/updateStatusPOST冻结/解冻子账户是JSON
/openApi/subAccount/v1/allAccountBalanceGET批量查询子账户资产概览是—
/openApi/subAccount/v1/apiKey/createPOST为子账户创建 API Key是JSON
/openApi/subAccount/v1/apiKey/editPOST编辑子账户 API Key是JSON
/openApi/subAccount/v1/apiKey/delPOST删除子账户 API Key是JSON
/openApi/account/v1/innerTransfer/authorizeSubAccountPOST授权子账户内部转账是表单
/openApi/wallets/v1/capital/subAccountInnerTransfer/applyPOST子账户内部转账是表单
/openApi/wallets/v1/capital/subAccount/deposit/addressGET获取子账户充值地址是—
/openApi/wallets/v1/capital/deposit/subHisrecGET获取子账户充值记录是—
/openApi/wallets/v1/capital/subAccount/innerTransfer/recordsGET查询子账户内部转账记录是—
/openApi/account/transfer/v1/subAccount/asset/transferHistoryGET查询子账户转账历史记录是—
/openApi/account/transfer/v1/subAccount/transferAsset/supportCoinsPOST查询可转账金额是表单
/openApi/account/transfer/v1/subAccount/transferAssetPOST子账户资产转账是表单
/openApi/v1/account/apiRestrictionsGET查询子账户 API Key 权限是—
/openApi/wallets/v1/capital/deposit/createSubAddressPOST为子账户创建充值地址是表单

参数

子账户参数
  • subAccountString:子账户用户名——必须以字母开头,包含数字,且长度超过 6 个字符
  • subUid:子账户 UID(长整数)
  • note:子账户或 API Key 的备注字符串
  • isFeeze:布尔值——按冻结状态筛选子账户(注意:API 参数名为 isFeeze,而非 isFreeze)
  • page:页码,从 1 开始
  • limit:每页数量,上限为 1000
  • freeze:布尔值——true 表示冻结,false 表示解冻
API Key 参数
  • apiKey:子账户的 API Key 字符串
  • uid:用户 UID(查询 API Key 信息时使用)
  • permissions:整数数组——要分配的权限(参见枚举)
  • ipAddresses:IP 地址字符串数组,用于白名单(可选)
转账参数
  • coin:货币/资产名称(例如,USDT)
  • amount / transferAmount:转账金额(浮点数)
  • userAccountType:1=UID,2=电话号码,3=邮箱
  • userAccount:收款方标识符(UID、电话或邮箱)
  • walletType / fromAccountType / toAccountType:账户类型(参见枚举)
  • fromUid / toUid:转账方/收款方 UID
  • fromType / toType:1=主账户,2=子账户
  • subUids:以逗号分隔的 UID 列表字符串(用于批量授权)
  • transferable:布尔值——true 表示允许,false 表示禁止内部转账
  • transferClientId:自定义客户端转账 ID 字符串
枚举

permissions(API Key 权限标志):

  • 1 — 现货交易
  • 2 — 读取
  • 3 — 永续合约交易
  • 4 — 通用转账
  • 5 — 提现
  • 7 — 允许子账户内部转账

walletType / accountType(账户类型代码):

  • 1 — 资金账户
  • 2 — 标准期货账户
  • 3 — 永续合约账户(USDⓢ-M)

status(充值记录状态):

  • 0 — 进行中
  • 1 — 已完成
  • 6 — 链上已上传
参数验证规则
  • subAccountString:必须以字母开头,至少包含一个数字,且长度超过 6 个字符
  • subUid:正整数(long)
  • coin:仅限大写字母和数字;格式 ^[A-Z0-9]{1,20}$(例如,USDT)
  • amount / transferAmount:必须为正数(> 0)
  • permissions:整数数组;每个值必须为 1, 2, 3, 4, 5, 7 之一
  • ipAddresses:提供时,每个值都必须是有效的 IPv4 地址
  • page:正整数,从 1 开始
  • limit:正整数,范围为 1–1000
  • recvWindow:整数,范围为 1–5000 ms(参见重放保护)
  • timestamp:Unix 毫秒时间;必须处于服务器时间的 recvWindow 范围内

快速开始

重要: 多个子账户写入端点要求使用 Content-Type: application/json,并将参数作为 JSON 请求体发送。对于这些调用,请传入 bodyType: "json"。所有其他 POST 端点均使用标准表单编码(bodyType: "form")。

约束:生成代码时,必须原样复制下面的 fetchSigned 函数。 不要重写签名、请求或 JSON 解析逻辑。仅修改:(1) 自定义环境的 BASE URL 条目;(2) 传递给 fetchSigned 的业务参数。有关支持 URL 编码 和 JSON 请求体的完整客户端,请参见 references/authentication.md。

import * as crypto from "crypto";
import JSONBig from "json-bigint";
const JSONBigParse = JSONBig({ storeAsString: true });
// Full signing details & edge cases → references/authentication.md
// Domain priority: .com is mandatory primary; .pro is fallback for network/timeout errors ONLY.
const BASE = {
  "prod-live": ["https://open-api.bingx.com", "https://open-api.bingx.pro"],
  "prod-vst":  ["https://open-api-vst.bingx.com", "https://open-api-vst.bingx.pro"],
};
function isNetworkOrTimeout(e: unknown): boolean {
  if (e instanceof TypeError) return true;
  if (e instanceof DOMException && e.name === "AbortError") return true;
  if (e instanceof Error && e.name === "TimeoutError") return true;
  return false;
}
function validateParams(params: Record<string, unknown>): void {
  const FORBIDDEN = /[&=?#\r\n]/;
  for (const [k, v] of Object.entries(params)) {
    const s = Array.isArray(v) ? JSON.stringify(v) : String(v);
    if (FORBIDDEN.test(s)) throw new Error(`Param "${k}" has forbidden char in: "${s}"`);
  }
}
async function fetchSigned(env: string, apiKey: string, secretKey: string,
  method: "GET" | "POST", path: string, params: Record<string, unknown> = {},
  bodyType: "form" | "json" = "form"
) {
  const urls = BASE[env] ?? BASE["prod-live"];
  const all = { ...params, timestamp: Date.now() };
  validateParams(all);
  const qs = Object.keys(all).sort().map(k => {
    const v = all[k]; return `${k}=${Array.isArray(v) ? JSON.stringify(v) : v}`;
  }).join("&");
  const sig = crypto.createHmac("sha256", secretKey).update(qs).digest("hex");
  for (const base of urls) {
    try {
      if (method === "GET") {
        const r = await fetch(`${base}${path}?${qs}&signature=${sig}`,
          { headers: { "X-BX-APIKEY": apiKey, "X-SOURCE-KEY": "BX-AI-SKILL" },
            signal: AbortSignal.timeout(10000) });
        const j = JSONBigParse.parse(await r.text()); if (j.code !== 0) throw new Error(`BingX error ${j.code}: ${j.msg}`);
        return j.data;
      }
      const ct = bodyType === "json" ? "application/json" : "application/x-www-form-urlencoded";
      const body = bodyType === "json" ? JSON.stringify({ ...all, signature: sig }) : `${qs}&signature=${sig}`;
      const r = await fetch(`${base}${path}`, { method: "POST",
        headers: { "X-BX-APIKEY": apiKey, "X-SOURCE-KEY": "BX-AI-SKILL", "Content-Type": ct }, body,
        signal: AbortSignal.timeout(10000) });
      const j = JSONBigParse.parse(await r.text()); if (j.code !== 0) throw new Error(`BingX error ${j.code}: ${j.msg}`);
      return j.data;
    } catch (e) {
      if (!isNetworkOrTimeout(e) || base === urls[urls.length - 1]) throw e;
    }
  }
}
代码使用规则
  • 必须原样复制 fetchSigned,不得简化或重写
  • 必须使用 json-bigint(JSONBigParse.parse)解析响应,不得使用 JSON.parse
  • 必须在每个请求中包含 X-SOURCE-KEY: BX-AI-SKILL 标头
  • 不得移除域名回退循环或 isNetworkOrTimeout 检查

常见调用

查询账户 UID:

const data = await fetchSigned("prod-live", API_KEY, SECRET, "GET",
  "/openApi/account/v1/uid"
);
// data.uid

创建子账户:

const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
  "/openApi/subAccount/v1/create",
  { subAccountString: "alice001", note: "trading sub" },
  "json"  // must use JSON body
);
// data.subUid, data.subAccountString

列出子账户(分页):

const data = await fetchSigned("prod-live", API_KEY, SECRET, "GET",
  "/openApi/subAccount/v1/list",
  { page: 1, limit: 100 }
);
// data.subAccountList[].uid, .subAccountString, .isFreeze

为子账户创建 API Key:

const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
  "/openApi/subAccount/v1/apiKey/create",
  {
    subUid: 16477999,
    note: "read-only key",
    permissions: [2],           // 2 = Read only
    ipAddresses: ["1.2.3.4"],
  },
  "json"  // must use JSON body
);
// data.apiKey, data.secretKey

冻结子账户:

await fetchSigned("prod-live", API_KEY, SECRET, "POST",
  "/openApi/subAccount/v1/updateStatus",
  { subUid: 16477999, freeze: true },
  "json"  // must use JSON body
);

在子账户之间转账资产(仅主账户):

const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
  "/openApi/account/transfer/v1/subAccount/transferAsset",
  {
    assetName: "USDT",
    transferAmount: 100,
    fromUid: 11111111,
    fromType: 1,           // 1 = master account
    fromAccountType: 1,    // 1 = fund account
    toUid: 22222222,
    toType: 2,             // 2 = sub-account
    toAccountType: 1,
    remark: "funding sub",
  }
  // default form body
);
// data.tranId

其他资源

所有 21 个端点的完整参数说明和响应架构,请参见 api-reference.md。


Agent 交互规则

参数安全。 从用户意图中提取结构化值——绝不要将用户的原始文本直接复制到 API 参数中。调用 API 前,根据文档规定的格式(正则表达式/枚举/范围)验证每个值。拒绝任何包含 &、=、?、# 或换行符的值。

所有写入操作在 prod-live 环境中都需要 CONFIRM。只读查询不需要。

  • prod-live:执行任何创建、编辑、删除、冻结或转账操作前,请让用户输入 CONFIRM。
  • prod-vst:无需 CONFIRM。告知用户:“您正在 Production Simulated (VST) 环境中操作。”
步骤 1 — 确定操作

如果用户的意图不明确,请提供以下选项:

您想要执行什么操作?

  • 查询账户 UID 或 API Key 权限
  • 创建新的子账户
  • 列出子账户
  • 查询子账户资产 / 资产概览
  • 冻结或解冻子账户
  • 创建 / 编辑 / 删除子账户 API Key
  • 查询子账户的 API Key
  • 授权子账户间内部转账
  • 在账户之间转移资产
  • 查询存款地址或存款记录
  • 查询转账历史
步骤 2 — 收集子账户标识符(如适用)

请提供子账户 UID;如果要创建新子账户,请提供子账户用户名。

步骤 3 — 收集操作所需的参数

创建子账户: 询问 subAccountString(必须以字母开头,包含数字,长度 >6 个字符)。询问可选的 note。

创建 / 编辑 API Key: 询问:

  • subUid(子账户 UID)
  • note(标签)
  • permissions(提供以下列表:1=现货,2=读取,3=永续期货,4=通用转账,5=提现,7=内部转账)
  • ipAddresses(可选的 IP 白名单)

冻结 / 解冻: 询问是否冻结(true)或解冻(false)。

资产转账: 询问:

  • assetName(例如,USDT)
  • transferAmount
  • 发送方 UID + 账户类型
  • 接收方 UID + 账户类型
步骤 4 — 确认(仅适用于生产环境实时写入操作)

您即将在 Production Live 上执行 {action}:

  • {参数摘要}

输入 CONFIRM 继续,或输入其他内容取消。

步骤 5 — 执行并报告

使用辅助函数执行 API 调用(对 create、updateStatus、apiKey/create、apiKey/edit、apiKey/del 使用 bodyType: "json";所有其他 POST 端点使用默认值 "form")。

向用户返回关键字段(例如,subUid、apiKey、tranId)。


JSON 请求体端点(提醒)

对于以下路径,始终传递 bodyType: "json":

  • POST /openApi/subAccount/v1/create
  • POST /openApi/subAccount/v1/updateStatus
  • POST /openApi/subAccount/v1/apiKey/create
  • POST /openApi/subAccount/v1/apiKey/edit
  • POST /openApi/subAccount/v1/apiKey/del

所有其他 POST 端点均使用默认的表单编码。

评论

支持 Markdown