@ bullletxyz/ sdk- wasm
网页大会 子弹 交易API。 在Node.js,浏览器,和德诺工作.
安装
npm install @bulletxyz/sdk-wasm
快速启动
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%):
如果平均填充价格低于标记价格,则交易返回
不止这样 填满比马克总是通过。 施受无量.
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 元数据 .
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
}
}
交易构建器
所有交易构建都通过构建者:
// 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() (这些
设置相同的单一独有性值,所以最后一个呼叫获胜:
const tx = Transaction.builder()
.callMessage(msg)
.nonce(42n) // or .generation(n) / .window(n)
.signer(keypair)
.send(client);
作为另一个账户执行
默认情况下,交易会作为签名人自己的默认地址执行. 使用
.addressOverride(address) 作为明确授权的账户予以执行
签名人的证书(如多相或委托账户)。 覆盖
作为交易的一部分签字并列入Borsh有效载荷
(单位:千美元)toBytes()和索拉纳离链JSON(toMessageBytes()) (中文(简体) ). 它需要一个
base58 地址并丢入无效地址.
const tx = Transaction.builder()
.callMessage(msg)
.addressOverride(multisigAddress) // base58 string
.signer(memberKeypair)
.build(client);
外部签名
对于可以签名标准的硬件钱包或外部签名服务 Borsh有效载荷:
// 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)包含
链式散列,所以可以符号的字节可以在没有客户引用的情况下被生成.
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(...) 也携带所需链条散列
使用当前序列器脱链验证器信封:
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 跨链格式(格式) 编程硬件钱包符号). 每个签名者都签名相同的字节; 一旦 符合交易的阈值.
// 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编码
余额桶和可选子账户索引:
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数字 :
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 对于一个可运行
保险库实例.
User.cancelQueuedWithdrawalV1(vault, withdrawalTimestamp?) 取消队列
其撤回 timestamp (从) queuedWithdrawals 打开 vault编号 :vaults(中文(简体) )
匹配,或者所有发件人排队从金库中提取
时间戳被省略。 年长者 User.cancelQueuedWithdrawal(vault) 取消数
只有最老的那个.
deriveSubAccountAddress(master, index) 计算子账户地址
其主地址和索引(0-31) (中文(简体) ). 转入子账户后,即产生该账户;
将索引传递到目的地 TransferEndpoint在那里交易,通过
索引为后缀 sub_account_index 关于命令/终止工厂的论据.
使用衍生地址读取 client.accountInfo(sub)。 。 。 .
离谱指数抛出.
曲速桥
桥接提取使用普通的打出呼叫信件和相同的交易 作为交换用户动作的构建器路径 :
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将其包括在交易活动中:
const response = await client.sendOffChainTransaction(tx);
response.messageId // string | undefined
网络安全套
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 改为
自定义重连接和闲置设置;其参数在类型声明中:
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() |
许可证
麻省理工学院