概述
KillB JavaScript SDK 提供了一个类型安全、易于使用的接口,用于将 KillB 的加密出入金 API 集成到您的 Node.js 或 TypeScript 应用程序中。安装
复制
npm install @killb/sdk
快速开始
初始化 SDK
复制
import { KillB } from '@killb/sdk';
const killb = new KillB({
email: process.env.KILLB_EMAIL,
password: process.env.KILLB_PASSWORD,
environment: 'sandbox' // 或 'production'
});
// SDK 自动处理身份验证
await killb.initialize();
配置选项
复制
interface KillBConfig {
email: string; // 您的 KillB 邮箱
password: string; // 您的 KillB 密码
apiKey?: string; // 可选的 API 密钥
environment?: 'sandbox' | 'production'; // 默认: 'sandbox'
timeout?: number; // 请求超时(毫秒)
retries?: number; // 最大重试次数
debug?: boolean; // 启用调试日志
}
核心功能
用户管理
复制
const user = await killb.users.create({
type: 'PERSON',
externalId: 'user-12345',
data: {
firstName: 'Juan',
lastName: 'García',
email: '[email protected]',
phone: '+573001234567',
dateOfBirth: '1990-01-01',
address: {
street1: 'Calle 123',
city: 'Bogotá',
state: 'Cundinamarca',
zipCode: '110111',
countryCode: 'CO'
},
document: {
type: 'PASSPORT',
number: 'AB123456',
issuedCountryCode: 'CO'
}
}
});
console.log('用户已创建:', user.id);
console.log('KYC 级别:', user.accessLevel);
账户管理
复制
const wallet = await killb.accounts.create({
type: 'WALLET',
userId: user.id,
externalId: 'wallet-polygon-usdc',
data: {
firstName: 'Juan',
lastName: 'García',
email: '[email protected]',
phone: '+573001234567',
currency: 'USDC',
network: 'POLYGON',
address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
countryCode: 'CO',
document: {
type: 'PASSPORT',
number: 'AB123456',
issuedCountryCode: 'CO'
}
}
});
console.log('钱包已创建:', wallet.id);
报价
复制
const quote = await killb.quotations.create({
fromCurrency: 'COP',
toCurrency: 'USDC',
amount: 100000,
amountIsToCurrency: false,
cashInMethod: 'PSE',
cashOutMethod: 'POLYGON'
});
console.log('汇率:', quote.rate);
console.log('您将收到:', quote.toAmount, 'USDC');
console.log('过期时间:', new Date(quote.expiresAt));
// 检查是否过期
if (quote.isExpired()) {
const newQuote = await killb.quotations.create(/* 相同参数 */);
}
出入金
复制
// 完整的入金流程
const ramp = await killb.ramps.create({
quotationId: quote.id,
userId: user.id,
accountId: wallet.id,
externalId: 'onramp-123'
});
console.log('出入金 ID:', ramp.id);
console.log('状态:', ramp.status);
console.log('支付 URL:', ramp.paymentInfo[0].url);
// 重定向用户到支付页面
// window.location.href = ramp.paymentInfo[0].url;
Webhooks
复制
const webhook = await killb.webhooks.create({
url: 'https://api.yourapp.com/webhooks/killb',
secret: process.env.WEBHOOK_SECRET,
events: ['RAMP', 'USER', 'ACCOUNT']
});
console.log('Webhook 已配置:', webhook.id);
储蓄账户
复制
const savings = await killb.savings.create({
userId: user.id,
acceptedTermsAndConditions: true
});
console.log('储蓄账户:', savings.id);
高级功能
分页
复制
// 自动分页辅助函数
const allUsers = await killb.users.listAll({
type: 'PERSON'
});
// 或手动分页
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await killb.users.list({ page, limit: 50 });
processUsers(result.users);
hasMore = page < result.totalPage;
page++;
}
错误处理
复制
import { KillBError, QuotationExpiredError, InsufficientBalanceError } from '@killb/sdk';
try {
const ramp = await killb.ramps.create(rampData);
} catch (error) {
if (error instanceof QuotationExpiredError) {
console.log('报价已过期,创建新报价...');
const newQuote = await killb.quotations.create(quoteParams);
return await killb.ramps.create({ ...rampData, quotationId: newQuote.id });
}
if (error instanceof InsufficientBalanceError) {
console.log('预存余额不足');
await notifyAdminToTopUp();
}
if (error instanceof KillBError) {
console.error('KillB API 错误:', error.code, error.message);
}
throw error;
}
重试配置
复制
const killb = new KillB({
email: process.env.KILLB_EMAIL,
password: process.env.KILLB_PASSWORD,
retryConfig: {
maxRetries: 3,
retryDelay: 1000,
retryableStatuses: [500, 502, 503, 504]
}
});
自定义请求头
复制
// 向请求添加自定义请求头
killb.setHeaders({
'X-Custom-Header': 'value',
'X-Request-ID': requestId
});
// 移除自定义请求头
killb.removeHeaders(['X-Custom-Header']);
请求日志
复制
const killb = new KillB({
email: process.env.KILLB_EMAIL,
password: process.env.KILLB_PASSWORD,
debug: true,
logger: {
log: (message) => console.log('[KillB]', message),
error: (message) => console.error('[KillB ERROR]', message)
}
});
完整示例
复制
import { KillB } from '@killb/sdk';
async function executeOnRamp(
walletAddress: string,
amount: number
) {
// 初始化 SDK
const killb = new KillB({
email: process.env.KILLB_EMAIL!,
password: process.env.KILLB_PASSWORD!,
environment: 'sandbox'
});
await killb.initialize();
try {
// 1. 创建用户
const user = await killb.users.create({
type: 'PERSON',
externalId: `user-${Date.now()}`,
data: {
firstName: 'Test',
lastName: 'User',
email: '[email protected]',
phone: '+573001234567',
dateOfBirth: '1990-01-01',
address: {
street1: 'Test Street 123',
city: 'Bogotá',
state: 'Cundinamarca',
zipCode: '110111',
countryCode: 'CO'
},
document: {
type: 'PASSPORT',
number: 'TEST123',
issuedCountryCode: 'CO'
}
}
});
console.log('✅ 用户已创建:', user.id);
// 2. 创建钱包账户
const wallet = await killb.accounts.create({
type: 'WALLET',
userId: user.id,
externalId: `wallet-${Date.now()}`,
data: {
firstName: 'Test',
lastName: 'User',
email: '[email protected]',
phone: '+573001234567',
currency: 'USDC',
network: 'POLYGON',
address: walletAddress,
countryCode: 'CO',
document: {
type: 'PASSPORT',
number: 'TEST123',
issuedCountryCode: 'CO'
}
}
});
console.log('✅ 钱包已创建:', wallet.id);
// 3. 获取报价
const quote = await killb.quotations.create({
fromCurrency: 'COP',
toCurrency: 'USDC',
amount: amount,
amountIsToCurrency: false,
cashInMethod: 'PSE',
cashOutMethod: 'POLYGON'
});
console.log('✅ 报价已创建:', quote.id);
console.log(' 汇率:', quote.rate);
console.log(' 您将收到:', quote.toAmount, 'USDC');
// 4. 创建出入金
const ramp = await killb.ramps.create({
quotationId: quote.id,
userId: user.id,
accountId: wallet.id,
externalId: `onramp-${Date.now()}`
});
console.log('✅ 出入金已创建:', ramp.id);
console.log(' 支付 URL:', ramp.paymentInfo[0].url);
// 5. 在沙盒环境中,模拟支付
if (killb.environment === 'sandbox') {
await killb.faker.cashIn(ramp.id);
console.log('✅ 支付已模拟');
}
// 6. 等待完成
const completed = await ramp.waitForCompletion({
pollInterval: 5000,
timeout: 300000
});
console.log('✅ 出入金已完成!');
console.log(' 转账证明:', completed.transferProof);
return completed;
} catch (error) {
console.error('❌ 错误:', error);
throw error;
}
}
// 使用
executeOnRamp('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', 100000)
.then(() => console.log('✅ 全部完成!'))
.catch(console.error);
TypeScript 支持
包含完整的 TypeScript 定义:复制
import type {
User,
CreateUserRequest,
Account,
CreateAccountRequest,
Ramp,
CreateRampRequest,
Quotation,
WebhookEvent
} from '@killb/sdk';
// 类型安全的操作
const createUser = async (data: CreateUserRequest): Promise<User> => {
return await killb.users.create(data);
};
工具函数
辅助函数
复制
// 验证地址
import { validateAddress } from '@killb/sdk/utils';
const isValid = validateAddress('0x742d35...', 'POLYGON');
console.log('有效地址:', isValid);
// 格式化货币
import { formatCurrency } from '@killb/sdk/utils';
const formatted = formatCurrency(1234.56, 'COP');
console.log(formatted); // "$ 1,234.56 COP"
// 计算费用
import { calculateFees } from '@killb/sdk/utils';
const fees = calculateFees(quote);
console.log('平台费用:', fees.platform);
console.log('网络费用:', fees.network);
console.log('总费用:', fees.total);
Webhook 验证
复制
import { verifyWebhookSignature } from '@killb/sdk';
// Express 中间件
const webhookMiddleware = (req, res, next) => {
const signature = req.headers['x-signature-sha256'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: '无效签名' });
}
next();
};
app.post('/webhooks/killb', webhookMiddleware, handleWebhook);
测试辅助函数(仅限沙盒)
复制
// 仅在沙盒环境中可用
if (killb.environment === 'sandbox') {
// 模拟入金
await killb.faker.cashIn(rampId);
// 模拟出金
await killb.faker.cashOut(rampId);
// 创建测试用户
const testUser = await killb.faker.createUser();
// 创建测试钱包
const testWallet = await killb.faker.createWallet(userId);
}
最佳实践
环境变量
环境变量
复制
// 使用环境变量存储凭据
const killb = new KillB({
email: process.env.KILLB_EMAIL!,
password: process.env.KILLB_PASSWORD!,
apiKey: process.env.KILLB_API_KEY,
environment: process.env.NODE_ENV === 'production'
? 'production'
: 'sandbox'
});
错误处理
错误处理
复制
// 始终在 try-catch 中包装 SDK 调用
try {
const result = await killb.ramps.create(data);
return result;
} catch (error) {
if (error instanceof KillBError) {
// 处理 KillB 特定错误
logError(error.code, error.message);
}
throw error;
}
复用 SDK 实例
复用 SDK 实例
复制
// 创建一次,在整个应用中复用
export const killb = new KillB(config);
// 在其他文件中
import { killb } from './killb-client';
const user = await killb.users.create(data);
使用外部 ID
使用外部 ID
复制
// 始终提供外部 ID 以实现幂等性
const ramp = await killb.ramps.create({
quotationId: quote.id,
userId: user.id,
accountId: wallet.id,
externalId: `order-${orderId}` // 您的系统 ID
});
API 参考
KillB 客户端
复制
class KillB {
constructor(config: KillBConfig)
// 初始化(使用前必须调用)
async initialize(): Promise<void>
// 资源管理器
users: UsersManager
accounts: AccountsManager
ramps: RampsManager
quotations: QuotationsManager
webhooks: WebhooksManager
savings: SavingsManager
customers: CustomersManager
banks: BanksManager
// 沙盒辅助函数
faker: FakerManager
// 静态工具函数
static verifyWebhookSignature(
payload: any,
signature: string,
secret: string
): boolean
}
资源管理器
每个资源都有一致的方法:复制
interface ResourceManager<T> {
create(data: CreateRequest): Promise<T>
get(id: string): Promise<T>
list(params?: ListParams): Promise<ListResponse<T>>
update(id: string, data: UpdateRequest): Promise<T>
delete(id: string): Promise<void>
}
从 REST API 迁移
之前(REST API)
复制
const response = await fetch('/api/v2/users', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(userData)
});
const user = await response.json();
之后(SDK)
复制
const user = await killb.users.create(userData);
- ✅ 无需手动身份验证请求头
- ✅ 自动令牌刷新
- ✅ 类型安全
- ✅ 更好的错误处理
- ✅ 更少的样板代码