txflow-sdk 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -200,6 +200,43 @@ const funding = await client.getFundingHistory({
200
200
  await client.requestFund("0xUSER_ADDRESS");
201
201
  ```
202
202
 
203
+ ### Sign Without Submitting
204
+
205
+ Every trading method has a corresponding `build*` method that returns the signed request payload without sending it to the API. This is useful for custom submission logic, queuing, or inspecting the signed data.
206
+
207
+ ```typescript
208
+ import { TxFlowClient, SignedRequest } from "txflow-sdk";
209
+
210
+ const client = new TxFlowClient({ privateKey: "0x..." });
211
+
212
+ const signed: SignedRequest = await client.buildPlaceOrder({
213
+ asset: 1,
214
+ isBuy: true,
215
+ price: "50000",
216
+ size: "0.01",
217
+ });
218
+
219
+ // signed = { action, signature: { r, s, v }, nonce, vaultAddress? }
220
+ // You now have full control over when and how to submit it.
221
+
222
+ // Submit later when ready:
223
+ const result = await client.submitSignedRequest(signed);
224
+ ```
225
+
226
+ Available `build*` methods:
227
+
228
+ | Method | Description |
229
+ |---|---|
230
+ | `buildPlaceOrder(params)` | Sign a single order |
231
+ | `buildPlaceBatchOrders(params[])` | Sign a batch of orders |
232
+ | `buildCancelOrder(params)` | Sign an order cancellation |
233
+ | `buildCancelOrders(params[])` | Sign multiple cancellations |
234
+ | `buildModifyOrder(params)` | Sign an order modification |
235
+ | `buildUpdateLeverage(params)` | Sign a leverage update |
236
+ | `buildUpdateMarginMode(params)` | Sign a margin mode update |
237
+
238
+ All `build*` methods accept the same parameters as their corresponding action methods and return a `SignedRequest` object.
239
+
203
240
  ## Advanced: Low-Level Signing
204
241
 
205
242
  For custom integrations, the signing primitives are exported directly:
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ethers } from "ethers";
2
- import type { TxFlowConfig, PlaceOrderParams, CancelOrderParams, ModifyOrderParams, UpdateLeverageParams, UpdateMarginModeParams, ApproveAgentParams, WithdrawParams, TransferTokenParams, SendTokenParams, ApiResponse, InfoResponse } from "./types.js";
2
+ import type { TxFlowConfig, SignedRequest, PlaceOrderParams, CancelOrderParams, ModifyOrderParams, UpdateLeverageParams, UpdateMarginModeParams, ApproveAgentParams, WithdrawParams, TransferTokenParams, SendTokenParams, ApiResponse, InfoResponse } from "./types.js";
3
3
  export declare class TxFlowClient {
4
4
  private wallet;
5
5
  private baseUrl;
@@ -22,6 +22,14 @@ export declare class TxFlowClient {
22
22
  withdraw(userWallet: ethers.Wallet, params: WithdrawParams): Promise<ApiResponse>;
23
23
  transferToken(userWallet: ethers.Wallet, params: TransferTokenParams): Promise<ApiResponse>;
24
24
  sendToken(userWallet: ethers.Wallet, params: SendTokenParams): Promise<ApiResponse>;
25
+ buildPlaceOrder(params: PlaceOrderParams): Promise<SignedRequest>;
26
+ buildPlaceBatchOrders(orderParams: PlaceOrderParams[]): Promise<SignedRequest>;
27
+ buildCancelOrder(params: CancelOrderParams): Promise<SignedRequest>;
28
+ buildCancelOrders(params: CancelOrderParams[]): Promise<SignedRequest>;
29
+ buildModifyOrder(params: ModifyOrderParams): Promise<SignedRequest>;
30
+ buildUpdateLeverage(params: UpdateLeverageParams): Promise<SignedRequest>;
31
+ buildUpdateMarginMode(params: UpdateMarginModeParams): Promise<SignedRequest>;
32
+ submitSignedRequest(signed: SignedRequest): Promise<ApiResponse>;
25
33
  getOpenOrders(user: string): Promise<InfoResponse>;
26
34
  getMultiUserOpenOrders(users: string[]): Promise<InfoResponse>;
27
35
  getMaxPositions(params: {
package/dist/client.js CHANGED
@@ -155,7 +155,7 @@ export class TxFlowClient {
155
155
  }
156
156
  async withdraw(userWallet, params) {
157
157
  const nonce = Date.now();
158
- const signatureChainId = params.signatureChainId ?? "0x66eee";
158
+ const signatureChainId = params.signatureChainId ?? "66eee";
159
159
  const message = {
160
160
  ofinChain: "ofin",
161
161
  destination: params.destination,
@@ -193,7 +193,7 @@ export class TxFlowClient {
193
193
  const signature = await signUserAction(userWallet, USER_ACTION_DOMAIN, TRANSFER_TOKEN_TYPES, message);
194
194
  return this.postExchange({
195
195
  action: {
196
- type: "transferToken",
196
+ type: "tokenSend",
197
197
  ofinChain: "ofin",
198
198
  amount: params.amount,
199
199
  fromAccountType: params.fromAccountType,
@@ -220,7 +220,7 @@ export class TxFlowClient {
220
220
  const signature = await signUserAction(userWallet, USER_ACTION_DOMAIN, SEND_TOKEN_TYPES, message);
221
221
  return this.postExchange({
222
222
  action: {
223
- type: "sendToken",
223
+ type: "tokenSend",
224
224
  ofinChain: "ofin",
225
225
  toAddress: params.toAddress,
226
226
  amount: params.amount,
@@ -233,6 +233,102 @@ export class TxFlowClient {
233
233
  signature: { r: signature.r, s: signature.s, v: signature.v },
234
234
  });
235
235
  }
236
+ async buildPlaceOrder(params) {
237
+ const order = this.buildOrderWire(params);
238
+ const action = { grouping: "na", orders: [order] };
239
+ const { signature, nonce } = await createSign(this.wallet, action, this.isMainnet, this.vaultAddress, this.chainId);
240
+ return {
241
+ action: { type: "order", grouping: "na", orders: [order], nonce },
242
+ signature: { r: signature.r, s: signature.s, v: signature.v },
243
+ nonce,
244
+ };
245
+ }
246
+ async buildPlaceBatchOrders(orderParams) {
247
+ const orders = orderParams.map((p) => this.buildOrderWire(p));
248
+ const action = { grouping: "na", orders };
249
+ const { signature, nonce } = await createSign(this.wallet, action, this.isMainnet, this.vaultAddress, this.chainId);
250
+ return {
251
+ action: { type: "order", grouping: "na", orders, nonce },
252
+ signature: { r: signature.r, s: signature.s, v: signature.v },
253
+ nonce,
254
+ };
255
+ }
256
+ async buildCancelOrder(params) {
257
+ const cancelAction = {
258
+ cancels: [{ a: params.asset, o: BigInt(params.orderId) }],
259
+ };
260
+ const { signature, nonce } = await createSign(this.wallet, cancelAction, this.isMainnet, this.vaultAddress, this.chainId);
261
+ return {
262
+ action: { type: "cancel", cancels: [{ a: params.asset, o: params.orderId }] },
263
+ signature: { r: signature.r, s: signature.s, v: signature.v },
264
+ nonce,
265
+ vaultAddress: this.vaultAddress,
266
+ };
267
+ }
268
+ async buildCancelOrders(params) {
269
+ const cancelAction = {
270
+ cancels: params.map((p) => ({ a: p.asset, o: BigInt(p.orderId) })),
271
+ };
272
+ const { signature, nonce } = await createSign(this.wallet, cancelAction, this.isMainnet, this.vaultAddress, this.chainId);
273
+ return {
274
+ action: {
275
+ type: "cancel",
276
+ cancels: params.map((p) => ({ a: p.asset, o: p.orderId })),
277
+ },
278
+ signature: { r: signature.r, s: signature.s, v: signature.v },
279
+ nonce,
280
+ vaultAddress: this.vaultAddress,
281
+ };
282
+ }
283
+ async buildModifyOrder(params) {
284
+ const order = this.buildOrderWire({
285
+ asset: params.asset,
286
+ isBuy: params.isBuy,
287
+ price: params.price,
288
+ size: params.size,
289
+ reduceOnly: params.reduceOnly,
290
+ timeInForce: params.timeInForce,
291
+ });
292
+ const modifyAction = { oid: BigInt(params.orderId), order };
293
+ const { signature, nonce } = await createSign(this.wallet, modifyAction, this.isMainnet, this.vaultAddress, this.chainId);
294
+ return {
295
+ action: { type: "modify", oid: params.orderId, order },
296
+ signature: { r: signature.r, s: signature.s, v: signature.v },
297
+ nonce,
298
+ vaultAddress: this.vaultAddress,
299
+ };
300
+ }
301
+ async buildUpdateLeverage(params) {
302
+ const action = { asset: params.asset, leverage: params.leverage };
303
+ const { signature, nonce } = await createSign(this.wallet, action, this.isMainnet, this.vaultAddress, this.chainId);
304
+ return {
305
+ action: { type: "updateLeverage", ...action },
306
+ signature: { r: signature.r, s: signature.s, v: signature.v },
307
+ nonce,
308
+ vaultAddress: this.vaultAddress,
309
+ };
310
+ }
311
+ async buildUpdateMarginMode(params) {
312
+ const action = { asset: params.asset, isCross: params.isCross };
313
+ const { signature, nonce } = await createSign(this.wallet, action, this.isMainnet, this.vaultAddress, this.chainId);
314
+ return {
315
+ action: { type: "updateMarginMode", ...action },
316
+ signature: { r: signature.r, s: signature.s, v: signature.v },
317
+ nonce,
318
+ vaultAddress: this.vaultAddress,
319
+ };
320
+ }
321
+ async submitSignedRequest(signed) {
322
+ const body = {
323
+ action: signed.action,
324
+ signature: signed.signature,
325
+ nonce: signed.nonce,
326
+ };
327
+ if (signed.vaultAddress !== undefined) {
328
+ body.vaultAddress = signed.vaultAddress;
329
+ }
330
+ return this.postExchange(body);
331
+ }
236
332
  async getOpenOrders(user) {
237
333
  return this.postInfo({ type: "openorders", user });
238
334
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "txflow-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "TypeScript SDK for TxFlow perpetual DEX with EIP-712 signing and MCP server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",