文档目录

TypeScript SDK

@tenergy/sdk 是针对平台 API 契约的强类型客户端:每个 operationId 均有对应的方法,类型定义直接源自 openapi.yaml,且每一次请求都会全自动按照 API 规范完成签名。

如果直接进行轻量级调用,您也可以参考 快速上手指南 中的二十行原生 tenergy() 辅助函数。

开始之前

SDK 的处理机制背后的设计原因
每次调用自动生成新鲜的时间戳与签名,包括重试签名具有单次有效性:重复使用旧签名会导致 1009 replayed_signature
序列化请求体一次并对这组字节串进行签名避免重复序列化格式微小差异导致签名不匹配 (1002)
仅对 GET 和 DELETE 在遇到 429、5xx 或可重试错误时自动退避重试(遵循 Retry-After)这些幂等读操作可以安全无副作用重试
POST 和 PATCH 请求绝不盲目重复发送网络超时的写操作可能已经在后台被执行;需使用相同 client_order_id 由业务层重试
除公开查询和注册接口外,每个私有调用都需要 apiKey + apiSecret针对免密钥的公开读取,可使用普通 fetch 直接调用 GET /v1/prices 或 /v1/estimate

步骤 1 — 创建客户端实例

import { TenergyClient } from "@tenergy/sdk";

const tenergy = new TenergyClient({
  baseUrl: "https://api-nile.tenergy.me/v1", // 主网请使用 https://api.tenergy.me/v1
  apiKey: process.env.TENERGY_KEY!, // Nile 测试网为 ak_test_…
  apiSecret: process.env.TENERGY_SECRET!, // 创建密钥时展示的 Secret
});
配置选项默认值说明
baseUrl— (必填)包含 /v1 前缀。末尾斜杠会自动剔除。
apiKey, apiSecret—签名调用必需。
timeoutMs15000单次请求超时时间(毫秒)。
retry{ maxRetries: 2, baseDelayMs: 200, maxDelayMs: 5000 }仅针对只读与安全幂等接口生效。
fetchglobalThis.fetch可自定义传入任意兼容 Fetch 签名的实现。

步骤 2 — 询价、下单并等待确认

const quote = await tenergy.createQuote({
  resource: "energy",
  amount: 65_000,
  tier: "1h",
  receiver: "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
});
const order = await tenergy.createOrder({ quote_id: quote.id, client_order_id: "payout-8821" });
const settled = await tenergy.waitForOrder(order.id, { timeoutMs: 30_000 });

if (settled.partial) console.log("已交付", settled.delivered_amount, "目标总量", settled.amount);

waitForOrder 方法会以 1 秒的间隔轮询 GET /v1/orders/{id},直到订单状态变为 active、expired、reclaimed、failed 或 refunded。如果发生超时,方法将抛出 TenergyTimeoutError 并附带最后一次查询到的订单快照 —— 订单本身并不会被取消。

步骤 3 — 异常与错误处理

import { TenergyApiError, TenergyTransportError } from "@tenergy/sdk";

try {
  await tenergy.createOrder({ quote_id: quote.id, client_order_id: "payout-8821" });
} catch (error) {
  if (error instanceof TenergyApiError && error.slug === "insufficient_funds") {
    // 账户余额不足:充值后使用相同的 client_order_id 重试,绝不会重复扣费
  } else if (error instanceof TenergyTransportError) {
    // 网络未收到响应:使用相同的 client_order_id 重试
  } else {
    throw error;
  }
}
错误类名触发场景包含的核心属性
TenergyApiErrorAPI 返回了标准的错误结构包code, slug, httpStatus, field, retryable, details, requestId, retryAfterSeconds
TenergyTransportError网络中断或网关故障(如 502/504)httpStatus, bodyExcerpt
TenergyTimeoutErrorwaitForOrder 轮询等待超时waitedMs, last

请务必按 slug 进行分支捕获,切勿根据英文 message 匹配。

步骤 4 — 验证 Webhook 签名

import { verifyWebhookSignature } from "@tenergy/sdk";

// rawBody: 接收到的原始请求体字节串,在进行任何 JSON 反序列化之前
const valid = verifyWebhookSignature(
  process.env.TENERGY_WEBHOOK_SECRET!,
  request.headers["x-api-timestamp"],
  rawBody,
  request.headers["x-api-sign"],
);

该工具函数验证签名;建议您自行检查 X-API-TIMESTAMP 是否在当前时间的 ±300 秒以内(防重放校验),详见 Webhooks 回调。

常用方法一览

模块方法列表
注册入驻createAccountChallenge, verifyAccountChallenge, createAccount, getSignupDepositAddress, bootstrap
账户管理getAccount, getBalance, listDepositAddresses
价格方案getPrices, estimateOrder, getOrderBook, createQuote, getQuote
订单管理createOrder, listOrders, getOrder (支持系统 ID 或 cid:<client_order_id>), reclaimOrder, waitForOrder
批量处理createBatch, listBatches, getBatch, cancelBatch
自动订阅createSubscription, listSubscriptions, getSubscription, updateSubscription, cancelSubscription
Webhook 回调createWebhook, listWebhooks, getWebhook, updateWebhook, deleteWebhook, rotateWebhookSecret, testWebhook
链上状态getAddressResources, estimateTransferEnergy
密钥管理listApiKeys, createApiKey, updateApiKey, deleteApiKey
签名工具signRequest, canonicalString, apiTimestamp, webhookSignature, verifyWebhookSignature

下一步

    ↑ ↓ 切换 · Enter 打开 · Esc 关闭