跳到主要内容

EVM 链与账户

Sparky 在 EVM 链上结算。本页说明身份模型、登录方式,以及"每条链一套部署"对接入方意味着什么。

1. 支持的网络

网络Chain ID部署备注
Avalanche C-Chain43114主网主结算链
Arbitrum One42161主网
BNB Chain56主网
Avalanche Fuji43113测试网测试 USDT,无实际价值
Arbitrum Sepolia421614测试网测试 USDT,无实际价值

每个网络由独立的后端进程服务,有各自的 Base URL(见 Base URL)。部署所结算的链由其 CHAIN_ID / RPC_URL 配置固定,并体现在 GET /api/v1/auth/nonce/{address} 返回的 EIP-712 domain 中。

2. 账户身份 = EOA 地址

你在 Sparky 的账户就是你的钱包地址,没有单独的用户 ID:

  • 余额、持仓、订单、API Key 与推荐数据都以小写 EOA 地址为键。
  • /fapi/v2/balanceaccountAlias 恒为 "default" —— 一个钱包地址对应且仅对应一个账户。
  • 两套引擎(Orderly 网关与 Sparky 自研)使用同一 EOA;Orderly 侧按地址派生 account_id,自研侧直接鉴权。

按链隔离

因为每条链都是独立部署:

  • **余额按链隔离。**充入 Avalanche Vault 只会记入你的 Avalanche 账户。
  • **持仓与订单按链隔离。**没有跨链保证金。
  • **API Key 按链隔离。**在你交易的每套部署上分别创建(每账户每部署最多 30 个)。
  • 推荐码按链隔离。

想要统一身份,在各链使用同一私钥即可;后端从不把各部署关联起来。

3. 登录(EIP-712 → JWT)

原生 /api/v1/* 使用对 EIP-712 typed data 签名换取的 JWT。/fapi/* 使用 JWT —— 它使用用 JWT 创建的 API Key(见 API Keys)。

客户端 ──① GET /api/v1/auth/nonce/{address} ──▶ nonce + typed_data
──② 用钱包对 typed_data 签名(链下)
──③ POST /api/v1/auth/login {address, signature, timestamp} ──▶ { token, expires_at }

3.1 获取 nonce 与 typed data

GET /api/v1/auth/nonce/{address}
{
"nonce": 1,
"typed_data": {
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Login": [
{ "name": "wallet", "type": "address" },
{ "name": "nonce", "type": "uint256" },
{ "name": "timestamp", "type": "uint256" }
]
},
"domain": {
"name": "AXBlade",
"version": "1",
"chainId": 43114,
"verifyingContract": "0x0000000000000000000000000000000000000000"
},
"primaryType": "Login",
"message": {
"wallet": "0xYourWalletAddress",
"nonce": 1,
"timestamp": 1700000000
}
}
}

domain.name 是为签名兼容保留的历史标识;请始终从该响应读取 domain 而不要硬编码。chainId 即部署所在链。

3.2 签名

// ethers.js v6
const { types, domain, message } = typed_data;
const { EIP712Domain, ...signTypes } = types; // ethers 会自动加上 domain 类型
const signature = await signer.signTypedData(domain, signTypes, message);

3.3 换取 JWT

POST /api/v1/auth/login
Content-Type: application/json
字段类型必填说明
addressstring钱包地址
signaturestring0x 开头的 EIP-712 签名
timestampnumber必须等于 typed_data.message.timestamp(Unix 秒);与服务器时间相差超过 300 秒返回 TIMESTAMP_EXPIRED
{ "token": "eyJhbGciOiJIUzI1NiIs...", "expires_at": 1700086400 }

之后每个 /api/v1/* 请求携带 Authorization: Bearer <token>expires_at 过后重新登录。

3.4 Privy 内嵌钱包

Sparky Web 端采用基于 Privy 的产品模型:用户以邮箱、Google 或外部钱包登录,Privy 生成内嵌 EOA,前端用 Privy access token 通过 POST /api/v1/auth/privy-login 换取 Sparky JWT。对这类会话,下单、撤单、TP/SL 与平仓只由 JWT 授权 —— 请求体里的 signature 字段是为兼容保留的历史字段,Privy 会话不再依赖它。

程序化接入方通常跳过 Privy,直接用上面的 EIP-712 流程登录,再为 /fapi 创建 API Key。

4. 该用哪套接口

你是…使用鉴权
机器人 / 做市商 / SDK 用户/fapi/v1/*/fapi/v2/*/futures/data/*X-MBX-APIKEY + HMAC-SHA256
需要充提或推荐的前端 / 脚本/api/v1/*Authorization: Bearer <JWT>
只读公开行情/fapi/v1/*/api/v1/markets/* 均可

API Key 不能提现。提现与推荐操作始终需要钱包派生的 JWT。