# @bulletxyz/sdk-wasm 中文文档

规范地址：https://npmcn.com/package/%40bulletxyz/sdk-wasm/

版本：0\.0\.47
npm 元数据更新时间：2026-11-04T19:31:39.103Z
中文译文更新时间：2026-11-08T19:32:36.271Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bulletxyz/sdk-wasm
原文对照：https://npmcn.com/package/%40bulletxyz/sdk-wasm/?lang=original
项目主页：https://bullet.xyz/
源码仓库：https://github.com/bulletxyz/bullet-rust-sdk

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：5.9 MB，13 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2026-03-30T21:44:16.926Z
- 最新版本发布：2026-11-04T19:31:38.744Z
- 近 30 天下载量：4272（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：38（近 12 个月 38 个）

## 中文简介

Web Assembly 用于子弹交易 SDK 的装订——在Node.js,浏览器和 Deno 工作

## 安装

```sh
npm install @bulletxyz/sdk-wasm
```

也可以使用：`pnpm add @bulletxyz/sdk-wasm`、`yarn add @bulletxyz/sdk-wasm`、`bun add @bulletxyz/sdk-wasm`

## README

# @ bullletxyz/ sdk- wasm

网页大会 [子弹](https://bullet.xyz/) 交易API。 在Node.js,浏览器,和德诺工作.

## 安装

```bash
npm install @bulletxyz/sdk-wasm
```

## 快速启动

```typescript
import { Client, Keypair, Transaction, User, NewOrderArgs, Side, OrderType } from '@bulletxyz/sdk-wasm';

const keypair = Keypair.fromHex('your-private-key');
const client = await Client.builder()
    .network('mainnet')
    .keypair(keypair)
    .build();

const marketId = client.marketId('BTC-USD');
if (marketId === undefined) throw new Error('unknown market');
const order = new NewOrderArgs('50000.0', '0.1', Side.Bid, OrderType.Limit, false);
const response = await Transaction.builder()
    .callMessage(User.placeOrders(marketId, [order], false))
    .send(client);
```

对于没有签名的市场数据,使用 `await Client.mainnet()` 并输入 方法,例如: `client.tickerPrice('BTC-USD')`。 。 。 .

### 脱源交易

使用键入 `DegenAction` 工厂将打开或关闭一个变质位置。 这个 动作直接传递到生成的没有 JSON 的呼叫信件 连载化.

`open` 在书上执行全部或无: `Side.Bid` 打开长和 `Side.Ask` 打开一个短句。 尺寸必须非零,并与市场一致 很大尺寸. `amountToTransfer` 以跨比值方式为单独余额供资 受协议限制为10美元. `close` 执行IOC并返回所剩部分 当位置平平时,孤立的平衡到相差.

`openV1` 财务报告和审定财务报表 `closeV1` 选择 `maxSlippageBps` (1个bps = 0.01%): 如果平均填充价格低于标记价格,则交易返回 不止这样 填满比马克总是通过。 施受无量.

```typescript
import { DegenAction, Side, User } from '@bulletxyz/sdk-wasm';

const open = User.degenTrade(
    7,
    DegenAction.open('5', Side.Bid, '10'),
);

const close = User.degenTrade(7, DegenAction.close(), 2);

// Revert if the average fill is more than 0.5% worse than mark.
const guardedOpen = User.degenTrade(7, DegenAction.openV1('5', Side.Bid, '10', 50));
const guardedClose = User.degenTrade(7, DegenAction.closeV1(50));
```

## API 参考

### 客户端

使用 `Client.mainnet()`, (中文(简体) ), `Client.connect(networkOrUrl)`,或上面显示的构建器. 已安装的软件包的TypeScript声明描述了所有的方法和参数. `client.cancelAndPlaceOrders(marketId, cancels, places, expiryTimestamp?, subAccountIndex?)` 取消订单,并将订单放入一份签名的交易中. `places` 不得为空.

默认情况下,客户端将验证每个交换的呼叫消息组 连接时的服务器计划 . `.userActions(['PlaceOrders', 'CancelOrders'])` 将验证限制在这些用户动作上,并在签名前拒绝其他动作. 构建器设置提供签名默认;交易构建器可以覆盖它们.

### 错误

易倒的WASM 调用 `BulletSdkError`,一个 Java 脚本 `Error` 子类为 解析 SDK 元数据 .

```typescript
import { BulletSdkError } from '@bulletxyz/sdk-wasm';

try {
    await client.accountBalance(address);
} catch (err) {
    if (err instanceof BulletSdkError) {
        err.kind       // 'api' | 'http' | 'websocket' | 'validation' | ...
        err.status     // HTTP status when the API returned one
        err.details    // structured JSON details when available
        err.errorId    // server-side correlation id, when present (for support)
        err.retryable  // whether retry/backoff is reasonable
        err.message    // human-readable message
    }
}
```

### 交易构建器

所有交易构建都通过构建者:

```typescript
// Build and send in one step
const response = await Transaction.builder()
    .callMessage(User.cancelAllOrders())
    .signer(keypair)
    .send(client);

// Build without sending
const tx = Transaction.builder()
    .callMessage(msg)
    .signer(keypair)
    .build(client);

const submitResponse = await client.sendTransaction(tx);
submitResponse.id       // transaction hash
submitResponse.status   // 'submitted' | 'processed' | ...
submitResponse.events   // LedgerEvent[]
```

### 独特性( 重放保护)

每个交易都带有独特的价值. 默认使用 SDK **基于窗口** 独有性来自跟踪 每笔交易的毫秒无九倍加分-单调, 不需要连锁往返并容忍许多 飞行中交易.

用任何一种来取代它 `.window()`, (中文(简体) ), `.generation()`,或 `.nonce()` (这些 设置相同的单一独有性值,所以最后一个呼叫获胜:

```typescript
const tx = Transaction.builder()
    .callMessage(msg)
    .nonce(42n)        // or .generation(n) / .window(n)
    .signer(keypair)
    .send(client);
```

### 作为另一个账户执行

默认情况下,交易会作为签名人自己的默认地址执行. 使用 `.addressOverride(address)` 作为明确授权的账户予以执行 签名人的证书(如多相或委托账户)。 覆盖 作为交易的一部分签字并列入Borsh有效载荷 (单位:千美元)`toBytes()`和索拉纳离链JSON(`toMessageBytes()`) (中文(简体) ). 它需要一个 base58 地址并丢入无效地址.

```typescript
const tx = Transaction.builder()
    .callMessage(msg)
    .addressOverride(multisigAddress) // base58 string
    .signer(memberKeypair)
    .build(client);
```

### 外部签名

对于可以签名标准的硬件钱包或外部签名服务 Borsh有效载荷:

```typescript
// Build unsigned (chain hash is baked in)
const unsigned = Transaction.builder()
    .callMessage(User.cancelAllOrders())
    .buildUnsigned(client);

// Get signable bytes and sign externally
const signable = unsigned.toBytes();
const display = unsigned.toDisplayMessage(); // optional: show in your own confirmation UI
const signature = myExternalSigner(signable);  // 64-byte Ed25519 signature

// Assemble the signed transaction
const signed = SignedTransaction.fromParts(unsigned, signature, pubKey);
await client.sendTransaction(signed);
```

### 未签名的交易

归来 `Transaction.builder().buildUnsigned(client)`包含 链式散列,所以可以符号的字节可以在没有客户引用的情况下被生成.

```typescript
unsigned.toBytes()  // Uint8Array — borsh signing payload: version byte, tx, chain hash (signable bytes)
unsigned.toDisplayMessage() // string — human-readable unsigned payload for display only
unsigned.toMessageBytes() // Uint8Array — readable JSON bytes for Solana wallets

// Inverse of toBytes(): rebuild an UnsignedTransaction from stored signable
// bytes (chain name comes from the client; mismatched chain hash is rejected).
UnsignedTransaction.fromBytes(bytes, client) // UnsignedTransaction
```

使用 `fromBytes` 当一个协调员(例如,一个多相干UI)持续交易时 作为它确切的可标志的字节并重建它以待展示和提交—— 重建的字节与签名的字节相同,所以存储的字节是 而不是一个单独的JSON代表.

`fromBytes` 只接受此签名格式产生的字节。 字节持续 无法重建 以序列化错误拒绝。 网络可能仍然承认 当环境遗留的断层打开时, 交易签名 (仅限单一签字人交易),但从其 输入并重新签名以安全.

显示一些外部钱包 `signMessage` 字节作为原始 UTF-8,所以 `toBytes()` 可以在钱包确认中显示为被套上。 这是预期的:这些字节是 网络验证。 使用 `toDisplayMessage()` 在您的应用程序 UI 中显示 在请求钱包签名前先进行交易内容 `toBytes()`。 。 。 .

对于钱包确认应显示可读的外部索拉纳钱包 JSON,用索拉纳断链路径代替. `toMessageBytes()` 返回时 可读 JSON 有效载荷 `chain_name`, (中文(简体) ), `details.chain_hash_fragment` 财务报告和审定财务报表 `version` 作为域. `SolanaOffchainTransaction.fromParts(...)` 也携带所需链条散列 使用当前序列器脱链验证器信封:

```typescript
const unsigned = Transaction.builder()
    .callMessage(User.cancelAllOrders())
    .buildUnsigned(client);

const message = unsigned.toMessageBytes();
const signature = await wallet.signMessage(message);
const pubKey = wallet.publicKey.toBytes(); // 32-byte Solana public key
const tx = SolanaOffchainTransaction.fromParts(unsigned, signature, pubKey);

await client.sendOffChainTransaction(tx);
```

### 已签名的交易

`Transaction.builder().build(client)` 财务报告和审定财务报表 `SignedTransaction.fromParts(...)` 制作签名交易. `toBytes()` 序列化 Borsh 信封; `toBase64()` 为 WebSocket 提交编码.

`SolanaOffchainTransaction.fromParts(...)` 将签名覆盖到 `unsigned.toMessageBytes()`。以 `client.sendOffChainTransaction(tx)`· ; 联合国 `toBytes()` 财务报告和审定财务报表 `toBase64()` 序列化离链信封.

### 多边形

M-of-N 跨链格式(格式) 编程硬件钱包符号). 每个签名者都签名相同的字节; 一旦 符合交易的阈值.

```typescript
// 2-of-3 multisig. Keys are canonicalized (sorted) internally, so input
// order never matters.
const config = new MultisigConfig(2, [pubkeyA, pubkeyB, pubkeyC]);

const unsigned = Transaction.builder()
    .callMessage(User.cancelAllOrders())
    .buildUnsigned(client);

// Collect signatures — each signer signs the same signable bytes
const tx = new SolanaLedgerMultisigTransaction(unsigned, config);
const signature = await ledgerWallet.signMessage(tx.signableBytes());
tx.addSignature(pubkeyA, signature);   // validates membership + signature
// ... pass tx.signableBytes() to the other signers ...
tx.addSignature(pubkeyB, signatureB);

// Submit (throws if below threshold)
await client.sendLedgerMultisigTransaction(tx);
```

可符号字节也可以在不集合交易的情况下生成: `unsigned.toLedgerMultisigSignableBytes(config)` (序言 + JSON)和 `unsigned.toMultisigMessageBytes(config)` (只有JSON有效载荷).

### 键盘

使用 `Keypair.generate()`, (中文(简体) ), `Keypair.fromHex(secret)` 或者说 `Keypair.fromBytes(bytes)`。 。 。 . 秘密是32字节; `publicKey()` 返回32字节的 Ed25519 公钥,并 `sign(bytes)` 返回一个64字节签名.

### 呼叫设备

生成命名空间( E)`User`, (中文(简体) ), `Public`, (中文(简体) ), `Keeper`, (中文(简体) ), `Vault`, (中文(简体) ), `Admin`, (中文(简体) ), `Warp`(中文(简体) ) 构建呼叫信息。 不允许的行动仍需要签署交易. 使用已安装的TypeScript声明用于工厂签名.

使用 `User.transfer` 平衡运动. `TransferEndpoint` 用JSON编码 余额桶和可选子账户索引:

```typescript
import { TransferEndpoint, User } from '@bulletxyz/sdk-wasm';

const deposit = User.transfer(
    new TransferEndpoint(JSON.stringify('bank')),
    new TransferEndpoint(JSON.stringify('cross')),
    0, '1000.0', '',
);
```

年长者 `User.deposit`, (中文(简体) ), `User.withdraw` 财务报告和审定财务报表 `User.createSubAccount` 工厂 仍然用于电线兼容性,但交换会拒绝这些行动.

代表过期编码为时代微秒. 如果你的应用商店时代 毫秒, 通过 `BigInt(expiresAtMs) * 1000n` 页:1 `expiresAt`。 。 。 .

将配置的代表读取为 `accountConfig`数字 :

```typescript
const config = await client.accountConfig(address);

for (const delegate of config.delegates) {
    delegate.address
    delegate.name
    delegate.flags
    delegate.expiresAt  // bigint | undefined, epoch microseconds
}
```

`deriveVaultAddress(name)` 从名字中计算出一个金库的地址. 见 [`examples/node/create_vault.ts`](https://npmcn.com/package/%40bulletxyz/examples/node/create_vault.ts) 对于一个可运行 保险库实例.

`User.cancelQueuedWithdrawalV1(vault, withdrawalTimestamp?)` 取消队列 其撤回 `timestamp` (从) `queuedWithdrawals` 打开 `vault`编号 :`vaults`(中文(简体) ) 匹配,或者所有发件人排队从金库中提取 时间戳被省略。 年长者 `User.cancelQueuedWithdrawal(vault)` 取消数 只有最老的那个.

`deriveSubAccountAddress(master, index)` 计算子账户地址 其主地址和索引(`0-31`) (中文(简体) ). 转入子账户后,即产生该账户; 将索引传递到目的地 `TransferEndpoint`在那里交易,通过 索引为后缀 `sub_account_index` 关于命令/终止工厂的论据. 使用衍生地址读取 `client.accountInfo(sub)`。 。 。 . 离谱指数抛出.

### 曲速桥

桥接提取使用普通的打出呼叫信件和相同的交易 作为交换用户动作的构建器路径 :

```typescript
import { Transaction, Warp } from '@bulletxyz/sdk-wasm';

const callMsg = Warp.transferRemote({
    warpRoute: '0x...',          // bytes32 route
    amount: '1000000',
    destinationDomain: 1234,
    gasPaymentLimit: '400000',
    recipient: '0x...',          // bytes32; 20-byte EVM hex is left-padded
    relayer: null,               // or a string / { Standard: string } / { Vm: string }
});

const unsigned = Transaction.builder()
    .callMessage(callMsg)
    .buildUnsigned(client);
```

使用小数字符串 `amount` 财务报告和审定财务报表 `gasPaymentLimit` 以上数值 `Number.MAX_SAFE_INTEGER`; 拒绝不安全的 JavaScript 数字以避免 签前四舍五入.

提交后,桥接响应会显示 Hyperlane 消息代号 交易API将其包括在交易活动中:

```typescript
const response = await client.sendOffChainTransaction(tx);
response.messageId  // string | undefined
```

### 网络安全套

```typescript
const ws = await client.connectWs();

// Subscribe to topics
await ws.subscribe([
    Topic.aggTrade('BTC-USD'),
    Topic.depth('ETH-USD', OrderbookDepth.D10),
    Topic.bookTicker('SOL-USD'),
    Topic.kline('BTC-USD', KlineInterval.H1),
    Topic.userDegenPositions('account-address'),
    Topic.allTickers(),
]);

// Receive messages
const msg = await ws.recv();
if (msg.type === 'degenPositionCompleted') {
    console.log(msg.data.position);
}

// Submit orders via WebSocket
const tx = Transaction.builder()
    .callMessage(User.placeOrders(0, [order], false))
    .signer(keypair)
    .build(client);

await ws.orderPlace(tx.toBase64());
```

### 管理 WebSocket(自动重新连接)

对于长跑的猪,更喜欢 `connectWsManaged` 它处理重接 与 指数回放并自动重放您的订阅 。 发送已排队; 以下列方式收到: `message` 事件。 命令队列时调用抛出 或背景任务已停止.

协议乒乓球保持原始套接字的活性,但不重置管理闲置 检测。 对于静静的订阅,发送应用程序 pings,捕获计时器错误, 并清除接收回路结束的时间间隔。 通过 a `ManagedWsConfig` 改为 自定义重连接和闲置设置;其参数在类型声明中:

```typescript
const ws = await client.connectWsManaged();

ws.subscribe([Topic.depth('BTC-USD', OrderbookDepth.D20)]);

const keepalive = setInterval(() => {
    try {
        ws.ping();
    } catch (err) {
        console.error('keepalive ping failed:', err);
    }
}, 30_000);

try {
    while (true) {
        const evt = await ws.recv();
        if (!evt) break;
        switch (evt.type) {
            case 'message':       handleMessage(evt.message); break;
            case 'reconnecting':  console.log('reconnecting...'); break;
            case 'disconnected':  console.error(evt.reason); return;
        }
    }
} finally {
    clearInterval(keepalive);
}
```

### 小数

价格和数量的固定精度小数计算。 首选字符串 投入,例如 `Decimal.fromScientific('1.5e2')` 以保持小数精确. 已检查算术( N)`checkedAdd`, (中文(简体) ), `checkedSub`, (中文(简体) ), `checkedMul`, (中文(简体) ), `checkedDiv`(中文(简体) ) 返回时 `undefined` 失败.

### REST API 方法

客户端将REST端点暴露为打入的同位素方法. 反应对象有: 键入式加 `toJSON()` jSON连载.

参数按字母顺序生成,而不是按"要求先"顺序生成,所以 必要的论据可以遵循无效的论据——通过 `null` 或者说 `undefined` 页:1 不需要的(例如: `client.orderBook(null, 'BTC-USD')`) (中文(简体) ). 标出参数 `?` 可能完全省略.

`userTransfers(action, address, asset, endTime, limit, startTime)` 接受一个 可选资产名称(例如) `'USDC'`)和逗号分隔的移动类型 (例如 `'DEPOSIT,WITHDRAWAL'`) (中文(简体) ). 两个过滤器都对大小写不敏感. 空 动作条目被忽略; 未知动作或完全空动作过滤器 返回 HTTP 400。 升级时插入 `null` 或者说 `undefined` 页:1 `asset` 在此之前 现有 `endTime`, (中文(简体) ), `limit`,以及 `startTime` 继续查询所有参数 资产.

`vaultEquity(address)` 返回用户在金库之间的活动位置 `totalEquity`每个职位包括: `vaultAddress`, (中文(简体) ), `shares`, (中文(简体) ), `equity`,则a 无效 `percentageReturn`。 。 。 .

每件物品由 `vaultDepositors` 包括持有、排队和总份额 加上股票,包括主金库账户及其金库所属分账户. 所有页面和定价来自一个承诺的滚动状态版本,报告为 `stateSlot`。 。 。 . `stateUpdatedAt` 是在收集该状态时(Unix) 微分秒数,默认情况下每30秒刷新一次,而不是块时间. `vaultEquity` 如果上次成功的收藏超过 90 个, 返回 HTTP 503 已过期秒; `vaultDepositors` 一直服务最后的好行.

打开 `vaultDepositors`,历史领域(`initialDepositAmount`, (中文(简体) ), `initialDepositTimestamp`, (中文(简体) ), `remainingCostBasis`, (中文(简体) ), `historyUpdatedAt`, (中文(简体) ), `historyLastTxNumber`, (中文(简体) ), `historyShares`)来自可选历史 投影,在无法使用时无效(或未在绑定中定义); stale 历史不阻断当前股份或股本. `historyComplete` 表示 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}不是说它赶上了现场 立场.

`percentageReturn` 必须显示为 **未实现收益估计数**打开 `vaultDepositors`, (中文(简体) ), `percentageReturnIsEstimate` 无论何时,都是真实的. `percentageReturn` 当历史超过30分钟,生活和 历史份额不同,剩余成本基础为零,或算术外溢. 打开 `vaultDepositors`,当国家收藏超过90时也是无效的 秒数; `vaultEquity` 返回 HTTP 503 替换为。 不是终生现金流 返回,不包括已实现的提款.

## 平台支持

| 平台 | 导入 |
| --- | --- |
| 节点.js | `import { Client } from '@bulletxyz/sdk-wasm'` |
| 德诺 | `import { Client } from '@bulletxyz/sdk-wasm'` |
| 浏览器 | `import init, { Client } from '@bulletxyz/sdk-wasm'` 接下来 `await init()` |

## 许可证

麻省理工学院

## 常见问题

### @bulletxyz/sdk-wasm 是什么？

Web Assembly 用于子弹交易 SDK 的装订——在Node\.js,浏览器和 Deno 工作

### 如何安装 @bulletxyz/sdk-wasm？

在项目目录运行 npm install @bulletxyz/sdk-wasm，或使用 pnpm add / yarn add / bun add。

### @bulletxyz/sdk-wasm 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bulletxyz/sdk-wasm 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @bulletxyz/sdk-wasm 可以商用吗？

@bulletxyz/sdk-wasm 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bulletxyz/sdk-wasm 的下载量有多少？

根据 npm 官方下载统计，@bulletxyz/sdk-wasm 在 2026/10/09 – 2026/11/07 这 30 天内被下载 4,272 次，日均约 142 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bulletxyz/sdk-wasm 还在维护吗？

最新版本 0\.0\.47 发布于 2026/11/05（4 天前）；至今共发布 38 个版本，其中过去 12 个月发布了 38 个；首次发布于 2026/03/31。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

