Appearance
变更记录
接口遵循以下兼容性约定:
- 在响应中新增字段、新增枚举取值(
status、subStatus、事件类型、错误码)、新增可选请求参数,都视为向后兼容的变更,不提升版本号。请让你的解析器忽略未知字段、容忍未知枚举值。 - 删除或重命名字段、改变字段含义等不兼容变更会使用新的路径前缀(如
/v2),并提前通知。
v1.0(2026-10)
首个对外版本。
认证
X-API-Key+Authorization: Bearer <JWT>,JWT 使用 Ed25519(EdDSA)签名,claims:uri、nonce、iat、exp(≤ 30 秒)、sub、bodyHash。- API Key 支持 IP 白名单(IP / CIDR)与每秒请求上限(默认 50)。
用户
POST /v1/users、GET /v1/users、GET /v1/users/{customerRefId}、PATCH /v1/users/{customerRefId}(邮箱、冻结/解冻)。POST /v1/users/{customerRefId}/deposit_address:一次调用创建用户与默认钱包并返回充值地址。GET /v1/users/{customerRefId}/balances:用户各资产余额汇总。customerRefId必填,邮箱可选;邮箱冲突返回409 EMAIL_TAKEN;冻结用户不能发起资金操作。
钱包与资产
POST /v1/wallets、GET /v1/wallets、GET /v1/wallets/{id}、GET /v1/wallets/{id}/assets、GET /v1/wallets/{id}/addresses。GET /v1/supported_assets(含当前生效的depositFeeRaw、withdrawFeeRaw)、GET /v1/networks。
交易
POST /v1/transactions:链上提现与站内转账(WALLET、END_USER、ONE_TIME_ADDRESS),本租户地址自动站内结算;externalTxId作为幂等键。- 可选的终端用户两步验证(
X-User-2FA-Code,租户开关,默认关闭)。 POST /v1/transactions/estimate_fee、GET /v1/transactions(按用户、钱包、类型、状态、资产、时间筛选)、GET /v1/transactions/{id}、GET /v1/transactions/external_tx_id/{externalTxId}、POST /v1/transactions/{id}/cancel、GET /v1/transactions/validate_address/{assetId}/{address}。- 充值手续费在入账时扣除,交易对象提供
netAmountRaw。
回调
GET/POST /v1/webhooks、PATCH/DELETE /v1/webhooks/{id}、POST /v1/webhooks/{id}/test、GET /v1/webhooks/deliveries、POST /v1/webhooks/events/{eventId}/resend、GET /v1/webhooks/public_key、GET /v1/webhooks/event_types。- 事件:
TRANSACTION_CREATED、TRANSACTION_STATUS_UPDATED、WALLET_CREATED、DEPOSIT_REVERSED、MANUAL_DEPOSIT_CREDITED、VAULT_GAS_LOW、WEBHOOK_TEST。 - Ed25519 签名(
X-WaaS-Signature: keyId=v1,sig=<hex>),失败重试 1m / 5m / 30m / 2h / 12h。
v1.1(2026-10-04)
向后兼容的小版本(新增字段/可选参数/错误语义):在响应中新增字段、在请求中新增可选参数、新增错误码取值都视为兼容,解析器请忽略未知字段。
用户
POST /v1/users新增可选请求字段password(writeOnly,写入新账号;必须与email一起提供)与nickname(≤32 字符)。重复的customerRefId仍返回原账号,且不会覆盖已有邮箱/密码/昵称。- 用户对象、余额、充值地址等接口均无破坏性变更。
订阅与访问
- 租户现在可能有订阅有效期。到期后所有
/v1与 C 端/app/v1请求返回403 FORBIDDEN(tenant subscription expired),无 GET 例外;请及时联系平台续期。平台续期为手工操作,无自动扣款。 - 租户被平台暂停(
tenant suspended)与订阅到期相互独立,续期不会自动解除暂停。
C 端注册(停用)
POST /app/v1/auth/register/code与POST /app/v1/auth/register已永久停用,一律返回403 FORBIDDEN(Self registration is disabled; contact your tenant),即使空请求体或非法 JSON 也一样。用户改由交易所通过POST /v1/users(可带password)或租户后台内部开户创建;历史C_DIRECT账号不受影响。此路径已标记deprecated,OpenAPI 中保留仅为兼容说明。
v1.2(2026-10-04)
向后兼容的小版本;新增管理员登录方式、资金池提款幂等头和正式域名。
正式域名
- B 端 API Base URL 改为
https://api.fablewallet.top;平台与租户后台为https://admin.fablewallet.top; 托管 C 端租户门户为https://{slug}.wallet.fablewallet.top,平台自营(slugplatform)使用根域名https://wallet.fablewallet.top;接入文档为https://docs.fablewallet.top。
管理员认证(控制台,非 B 端接口)
- 平台与租户管理员统一使用本地加密 Ed25519 凭证 + 强制 TOTP登录。固定密码管理员登录
POST /admin/v1/auth/login、POST /tenant-admin/v1/auth/login永久停用,不解析请求体,一律403 FORBIDDEN, 即使请求体为空或非法也一样;没有固定密码登录回退。 - 凭证登录(匿名自助,
security: []):- 平台:
POST /admin/v1/auth/challenge {keyId}→POST /admin/v1/auth/key-login {keyId,signature,totp?}; - 租户:
POST /tenant-admin/v1/auth/challenge {tenantSlug,keyId}→POST /tenant-admin/v1/auth/key-login {tenantSlug,keyId,signature,totp?}。 - 挑战一次性、120 秒有效,绑定 scope/租户,仅对已知且有效的凭证签发;签名原文为
waas-admin-login:v1:<challenge>。 - 首次凭证签名验证通过只返回
{step:"enrollTotp", enrollmentToken, secret, otpauthUrl},不创建会话;完成POST /admin/v1/auth/enroll {enrollmentToken, code}或POST /tenant-admin/v1/auth/enroll {tenantSlug,enrollmentToken, code}绑定后才返回{step:"authenticated", accessToken, expiresIn, admin}。已绑定管理员必须提供有效 TOTP: 未提供返回403 TWO_FACTOR_REQUIRED,错误或同一验证码二次使用返回403 TWO_FACTOR_INVALID。 - 吊销凭证会阻断未完成的 enrollment,并注销该管理员所有会话;其他设备仍可用“凭证 + TOTP”重新登录。
- 平台:
- 控制台(平台
/admin/v1、租户/tenant-admin/v1)除认证入口外的业务路径使用会话 Bearer(AdminBearer), 不再是匿名。平台管理员的敏感写操作仍由平台双人复核保护。这些路径不属于 B 端/v1对接范围。
平台管理接口
- 新增
POST /admin/v1/tenants(OWNER,平台双人复核):请求体{slug,name,ownerEmail,ownerPublicKey,expiresAt?},ownerPublicKey为 owner 本地持有的 32 字节 Ed25519 公钥(64 hex);不接收ownerPassword。普通调用返回202 {changeId,status:"PENDING"},另一名OWNER批准后才真正创建。 - 新增
POST /admin/v1/tenants/{id}/admins(CONFIG/OWNER,平台双人复核):请求体{email,publicKey,roles}, 不接收password。未知字段(含密码/私钥/解锁口令)在入队前即422 BAD_REQUEST,不落成待复核变更单。 PUT /admin/v1/tenants/{id}/subscription请求体必须恰好含expiresAt(RFC 3339 或null),先入平台双人复核队列: 普通调用只得到202 {changeId,status:"PENDING"},202 不等于生效;批准后的200才是复核发布后的业务结果。 缺字段、多字段或格式错误返回422 BAD_REQUEST(不是400)。
错误语义
- 手写校验(缺少/非法
Idempotency-Key、expiresAt、keyId、签名或请求体字段)与业务校验一样返回422 BAD_REQUEST;仅路径/查询参数解析失败由框架返回400。tenant-admin/v1/vault-payouts缺少Idempotency-Key为422,同 key 不同请求体为409 IDEMPOTENCY_CONFLICT,角色/step-up 2FA 不足为403。
资金池提款
POST /tenant-admin/v1/vault-payouts新增必填Idempotency-Key:同请求体同 key 返回原提款单, 同 key 不同请求体返回409 IDEMPOTENCY_CONFLICT;角色、step-up 2FA 与另一名管理员审批不变。- 新增
GET /tenant-admin/v1/withdrawal-assets:只返回本租户已开放网络的可提款资产元数据 (assetId/symbol/name/decimals/networkKey/kind,无费率设置),订阅到期后仍可访问。
用户
POST /v1/users与租户后台内部开户对同一customerRefId仍幂等:重复返回首次创建的账号, 不覆盖已有邮箱/密码/昵称(与 v1.1 一致)。- C 端自助注册保持永久停用;用户承担充提成本、平台配置只作租户默认值的决定不变。