bloque-sdk-ts
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBloque SDK Integration
Bloque SDK 集成指南
TypeScript SDK for programmable financial infrastructure: accounts, cards, spending controls, transfers, and webhooks.
用于可编程金融基础设施的TypeScript SDK:涵盖账户、卡片、支出控制、转账及Webhook功能。
When to Apply
适用场景
Use this skill when:
- Integrating the Bloque SDK into a new or existing project
- Creating accounts (virtual pockets, cards, Polygon wallets, bank accounts)
- Setting up card spending controls (default or smart MCC routing)
- Handling card transaction webhooks
- Transferring funds between accounts (single or batch)
- Building budgeting or expense-management features
- Querying balances or transaction history
在以下场景中使用本技能:
- 将Bloque SDK集成到新的或现有项目中
- 创建账户(虚拟口袋、卡片、Polygon钱包、银行账户)
- 设置卡片支出控制(默认模式或智能MCC路由)
- 处理卡片交易Webhook
- 在账户间转账(单笔或批量)
- 构建预算或支出管理功能
- 查询余额或交易历史
SDK at a Glance
SDK概览
@bloque/sdk → Main package (aggregates everything)
@bloque/sdk-core → HttpClient, errors, types
@bloque/sdk-accounts → Accounts, cards, transfers
@bloque/sdk-identity → User identities and aliases
@bloque/sdk-compliance → KYC/KYB verification
@bloque/sdk-orgs → Organizations
@bloque/sdk-swap → Currency swap and bank transfersPlatforms: Node.js, Bun, Deno (API key auth) | Browser, React Native (JWT auth)
Assets: , , ,
Amounts: Always strings to preserve precision. = 10 DUSD (6 decimals).
DUSD/6COPB/6COPM/2KSM/12"10000000"@bloque/sdk → 主包(整合所有功能)
@bloque/sdk-core → HttpClient、错误处理、类型定义
@bloque/sdk-accounts → 账户、卡片、转账功能
@bloque/sdk-identity → 用户身份与别名管理
@bloque/sdk-compliance → KYC/KYB验证
@bloque/sdk-orgs → 组织管理
@bloque/sdk-swap → 货币兑换与银行转账支持平台:Node.js、Bun、Deno(API密钥认证)| 浏览器、React Native(JWT认证)
支持资产:、、、
金额格式:始终以字符串形式保存以保证精度。例如等价于10 DUSD(保留6位小数)。
DUSD/6COPB/6COPM/2KSM/12"10000000"Quick Start
快速开始
typescript
import { SDK } from '@bloque/sdk';
const bloque = new SDK({
origin: process.env.ORIGIN,
auth: { type: 'apiKey', apiKey: process.env.API_KEY },
mode: 'sandbox',
});
// Register a new user
await bloque.register('@alice', {
type: 'individual',
profile: { firstName: 'Alice', lastName: 'Smith', email: 'alice@example.com',
phone: '+1234567890', birthdate: '1990-01-01', city: 'Miami', state: 'FL',
postalCode: '33101', countryOfBirthCode: 'US', countryOfResidenceCode: 'US' },
});
// Connect to an existing user
const user = await bloque.connect('@alice');
// Create a pocket and a card
const pocket = await user.accounts.virtual.create({}, { waitLedger: true });
const card = await user.accounts.card.create(
{ ledgerId: pocket.ledgerId, name: 'My Card' },
{ waitLedger: true },
);typescript
import { SDK } from '@bloque/sdk';
const bloque = new SDK({
origin: process.env.ORIGIN,
auth: { type: 'apiKey', apiKey: process.env.API_KEY },
mode: 'sandbox',
});
// 注册新用户
await bloque.register('@alice', {
type: 'individual',
profile: { firstName: 'Alice', lastName: 'Smith', email: 'alice@example.com',
phone: '+1234567890', birthdate: '1990-01-01', city: 'Miami', state: 'FL',
postalCode: '33101', countryOfBirthCode: 'US', countryOfResidenceCode: 'US' },
});
// 连接现有用户
const user = await bloque.connect('@alice');
// 创建虚拟口袋和卡片
const pocket = await user.accounts.virtual.create({}, { waitLedger: true });
const card = await user.accounts.card.create(
{ ledgerId: pocket.ledgerId, name: 'My Card' },
{ waitLedger: true },
);References
参考文档
For deeper guidance, read these files in order of relevance to the task:
| File | When to read |
|---|---|
| Read first for any integration. All methods, params, and exact return types. |
| First-time setup, configuration, auth strategies |
| Creating pockets, Polygon wallets, bank accounts |
| Card creation, default/smart spending, MCC routing |
| Handling transaction events, webhook payloads |
| Moving funds, batch transfers, movement metadata |
如需更深入的指导,请按与任务相关的优先级顺序阅读以下文档:
| 文档文件 | 阅读时机 |
|---|---|
| 任何集成场景下都请首先阅读。包含所有方法、参数及精确的返回类型。 |
| 首次设置、配置、认证策略相关内容 |
| 创建虚拟口袋、Polygon钱包、银行账户相关内容 |
| 卡片创建、默认/智能支出控制、MCC路由相关内容 |
| 处理交易事件、Webhook负载相关内容 |
| 资金划转、批量转账、转账元数据相关内容 |
Key Concepts
核心概念
- Pockets — Virtual accounts that hold funds. Every card must be linked to a pocket via .
ledgerId - Spending Controls — (one pocket, all merchants) or
"default"(MCC-based multi-pocket routing)."smart" - MCC Routing — Map Merchant Category Codes to pockets. Priority order determines fallback.
- Webhooks — Async events for card transactions (authorization, adjustment). Delivered to .
webhookUrl - Assets — Format is . Amounts are raw integer strings.
SYMBOL/DECIMALS.10 DUSD = "10000000"
- Pockets(虚拟口袋) — 用于存放资金的虚拟账户。每张卡片必须通过关联到一个虚拟口袋。
ledgerId - 支出控制 — 分为(单口袋,支持所有商户)或
"default"(基于MCC的多口袋路由)模式。"smart" - MCC路由 — 将商户类别码(MCC)映射到不同虚拟口袋。优先级顺序决定了 fallback 逻辑。
- Webhook — 用于卡片交易(授权、调整)的异步事件。会推送至指定的。
webhookUrl - 资产格式 — 格式为。金额以原始整数字符串表示。例如10 DUSD等价于
SYMBOL/DECIMALS。"10000000"
Critical: Alias Consistency
重要提示:别名一致性
The alias used in and MUST be identical. If you register a user as , you must connect with exactly — not , , or any variation. A mismatch will throw a ("identity not found").
register()connect()'@alice''@alice''alice''@Alice'BloqueNotFoundErrortypescript
// Register
await bloque.register('@alice', { type: 'individual', profile: { ... } });
// Connect — MUST use the exact same alias
const user = await bloque.connect('@alice'); // ✅ correct
const user = await bloque.connect('alice'); // ❌ BloqueNotFoundError
const user = await bloque.connect('@Alice'); // ❌ BloqueNotFoundErrorRule: Pick one alias string and reuse it everywhere. Store it in a constant or environment variable.
register()connect()'@alice''@alice''alice''@Alice'BloqueNotFoundErrortypescript
// 注册
await bloque.register('@alice', { type: 'individual', profile: { ... } });
// 连接 — 必须使用完全相同的别名
const user = await bloque.connect('@alice'); // ✅ 正确
const user = await bloque.connect('alice'); // ❌ 抛出BloqueNotFoundError
const user = await bloque.connect('@Alice'); // ❌ 抛出BloqueNotFoundError规则:选择一个别名字符串并在所有地方复用。将其存储在常量或环境变量中。
Critical: connect()
Always Succeeds
connect()重要提示:connect()
始终返回会话
connect()connect()register()user.accounts.card.create()The SDK does NOT provide a "user exists" check. Your application must track whether a user has been registered before calling .
connect()typescript
// ❌ Wrong — no way to know if '@bob' was ever registered
const user = await bloque.connect('@bob'); // Returns session (no error!)
const card = await user.accounts.card.create(); // 💥 Fails here — identity not found
// ✅ Correct — track registration state in your app
const isRegistered = await db.users.exists('@bob');
if (!isRegistered) {
await bloque.register('@bob', { type: 'individual', profile: { ... } });
await db.users.markRegistered('@bob');
}
const user = await bloque.connect('@bob');Rule: Never assume validates the user. Always ensure has been called first, using your own application logic.
connect()register()connect()register()user.accounts.card.create()connect()typescript
// ❌ 错误做法 — 无法确认'@bob'是否已注册
const user = await bloque.connect('@bob'); // 返回会话(无错误!)
const card = await user.accounts.card.create(); // 💥 此处失败 — 身份未找到
// ✅ 正确做法 — 在您的应用中跟踪注册状态
const isRegistered = await db.users.exists('@bob');
if (!isRegistered) {
await bloque.register('@bob', { type: 'individual', profile: { ... } });
await db.users.markRegistered('@bob');
}
const user = await bloque.connect('@bob');规则:永远不要假设会验证用户身份。务必确保在调用之前已通过您自己的应用逻辑完成调用。
connect()connect()register()Error Handling
错误处理
All errors extend and include , , and :
BloqueAPIErrorrequestIdtimestamptoJSON()| Error Class | HTTP | When |
|---|---|---|
| 400 | Invalid params |
| 401/403 | Bad API key or JWT |
| 404 | Resource missing |
| 429 | Too many requests |
| — | Not enough balance |
| — | Connection failed |
| — | Request timed out |
typescript
import { BloqueInsufficientFundsError } from '@bloque/sdk-core';
try {
await user.accounts.transfer({ sourceUrn, destinationUrn, amount, asset });
} catch (err) {
if (err instanceof BloqueInsufficientFundsError) {
console.log('Not enough funds:', err.toJSON());
}
}所有错误均继承自,并包含、及方法:
BloqueAPIErrorrequestIdtimestamptoJSON()| 错误类 | HTTP状态码 | 触发场景 |
|---|---|---|
| 400 | 参数无效 |
| 401/403 | API密钥或JWT无效 |
| 404 | 资源不存在 |
| 429 | 请求过于频繁 |
| — | 余额不足 |
| — | 连接失败 |
| — | 请求超时 |
typescript
import { BloqueInsufficientFundsError } from '@bloque/sdk-core';
try {
await user.accounts.transfer({ sourceUrn, destinationUrn, amount, asset });
} catch (err) {
if (err instanceof BloqueInsufficientFundsError) {
console.log('余额不足:', err.toJSON());
}
}