@nightlylabs/dex-sdk 0.0.24 → 0.0.25

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/dist/index.cjs CHANGED
@@ -50,12 +50,15 @@ __export(index_exports, {
50
50
  getRandomId: () => getRandomId,
51
51
  getTopicFromCommand: () => getTopicFromCommand,
52
52
  getTopicFromMessage: () => getTopicFromMessage,
53
+ nowInMiliseconds: () => nowInMiliseconds,
54
+ parseEntryFunctionAbi: () => parseEntryFunctionAbi,
53
55
  sleep: () => sleep,
54
56
  toSystemValue: () => toSystemValue
55
57
  });
56
58
  module.exports = __toCommonJS(index_exports);
57
59
 
58
60
  // src/client.ts
61
+ var import_ts_sdk2 = require("@aptos-labs/ts-sdk");
59
62
  var import_surf = require("@thalalabs/surf");
60
63
  var import_isomorphic_ws = __toESM(require("isomorphic-ws"), 1);
61
64
  var import_uuid = require("uuid");
@@ -513,6 +516,7 @@ var GLOBAL_DENOMINATOR = 1e8;
513
516
  // src/utils.ts
514
517
  var import_decimal = require("decimal.js");
515
518
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
519
+ var nowInMiliseconds = () => Date.now();
516
520
  var toSystemValue = (value) => {
517
521
  return new import_decimal.Decimal(value).mul(new import_decimal.Decimal(GLOBAL_DENOMINATOR)).toString();
518
522
  };
@@ -580,6 +584,184 @@ var getTopicFromMessage = (data) => {
580
584
  }
581
585
  };
582
586
 
587
+ // src/sequenceNumberManager.ts
588
+ var AccountSequenceNumber = class {
589
+ /**
590
+ * Creates an instance of AccountSequenceNumber.
591
+ *
592
+ * @param aptos - The Aptos client instance
593
+ * @param account - The account associated with transactions
594
+ * @param options - Configuration options
595
+ */
596
+ constructor(aptos, account, options = {}) {
597
+ // Sequence number on chain
598
+ this.lastCommittedNumber = null;
599
+ // Local sequence number (next to be used)
600
+ this.currentNumber = null;
601
+ // Use a proper mutex implementation instead of a boolean flag
602
+ this.isLocked = false;
603
+ this.lockQueue = [];
604
+ this._aptos = aptos;
605
+ this.account = account;
606
+ this.maxWaitTime = options.maxWaitTime ?? 1e4;
607
+ this.maximumInFlight = options.maximumInFlight ?? 100;
608
+ this.sleepTime = options.sleepTime ?? 10;
609
+ this.warningTime = options.warningTime ?? 3e4;
610
+ }
611
+ /**
612
+ * Acquires the lock for synchronized access.
613
+ */
614
+ async acquireLock() {
615
+ if (!this.isLocked) {
616
+ this.isLocked = true;
617
+ return;
618
+ }
619
+ return new Promise((resolve) => {
620
+ this.lockQueue.push(resolve);
621
+ });
622
+ }
623
+ /**
624
+ * Releases the lock and processes the next queued operation if any.
625
+ */
626
+ releaseLock() {
627
+ if (this.lockQueue.length > 0) {
628
+ const nextResolve = this.lockQueue.shift();
629
+ if (nextResolve) {
630
+ nextResolve();
631
+ }
632
+ } else {
633
+ this.isLocked = false;
634
+ }
635
+ }
636
+ /**
637
+ * Returns the next available sequence number for this account.
638
+ *
639
+ * @returns The next available sequence number or null if an error occurs
640
+ */
641
+ async nextSequenceNumber() {
642
+ await this.acquireLock();
643
+ try {
644
+ if (this.lastCommittedNumber === null || this.currentNumber === null) {
645
+ await this.initialize();
646
+ }
647
+ if (this.currentNumber - this.lastCommittedNumber >= this.maximumInFlight) {
648
+ await this.waitForCommit();
649
+ }
650
+ const nextNumber = this.currentNumber;
651
+ this.currentNumber = this.currentNumber + BigInt(1);
652
+ return nextNumber;
653
+ } catch (e) {
654
+ console.error("Error getting next sequence number:", e);
655
+ return null;
656
+ } finally {
657
+ this.releaseLock();
658
+ }
659
+ }
660
+ /**
661
+ * Waits for pending transactions to be committed.
662
+ */
663
+ async waitForCommit() {
664
+ await this.update();
665
+ const startTime = nowInMiliseconds();
666
+ while (this.currentNumber - this.lastCommittedNumber >= this.maximumInFlight) {
667
+ const elapsed = nowInMiliseconds() - startTime;
668
+ if (elapsed > this.maxWaitTime) {
669
+ console.warn(
670
+ `Waited over ${this.maxWaitTime / 1e3} seconds for a transaction to commit, re-syncing ${this.account.accountAddress.toString()}`
671
+ );
672
+ await this.initialize();
673
+ break;
674
+ }
675
+ if (elapsed > this.warningTime && elapsed % 5e3 < this.sleepTime) {
676
+ console.warn(
677
+ `Still waiting for transactions to commit after ${elapsed / 1e3} seconds for account ${this.account.accountAddress.toString()}`
678
+ );
679
+ }
680
+ await sleep(this.sleepTime);
681
+ await this.update();
682
+ }
683
+ }
684
+ /**
685
+ * Initializes this account with the sequence number on chain.
686
+ */
687
+ async initialize() {
688
+ const sequenceNumber = await this.getSequenceNumber();
689
+ this.currentNumber = sequenceNumber;
690
+ this.lastCommittedNumber = sequenceNumber;
691
+ }
692
+ /**
693
+ * Updates this account's sequence number with the one on-chain.
694
+ *
695
+ * @returns The on-chain sequence number for this account.
696
+ */
697
+ async update() {
698
+ const sequenceNumber = await this.getSequenceNumber();
699
+ this.lastCommittedNumber = sequenceNumber;
700
+ return this.lastCommittedNumber;
701
+ }
702
+ /**
703
+ * Synchronizes the local sequence number with the sequence number on-chain.
704
+ * This method waits until all submitted transactions have been committed.
705
+ */
706
+ async synchronize() {
707
+ if (this.lastCommittedNumber === this.currentNumber) return;
708
+ await this.acquireLock();
709
+ try {
710
+ await this.update();
711
+ const startTime = nowInMiliseconds();
712
+ while (this.lastCommittedNumber !== this.currentNumber) {
713
+ const elapsed = nowInMiliseconds() - startTime;
714
+ if (elapsed > this.maxWaitTime) {
715
+ console.warn(
716
+ `Waited over ${this.maxWaitTime / 1e3} seconds for all transactions to commit, re-syncing ${this.account.accountAddress.toString()}`
717
+ );
718
+ await this.initialize();
719
+ break;
720
+ }
721
+ await sleep(this.sleepTime);
722
+ await this.update();
723
+ }
724
+ } catch (e) {
725
+ console.error("Error synchronizing account sequence number:", e);
726
+ } finally {
727
+ this.releaseLock();
728
+ }
729
+ }
730
+ /**
731
+ * Gets the current sequence number from the blockchain.
732
+ *
733
+ * @returns The current sequence number
734
+ * @throws If unable to retrieve the account information
735
+ */
736
+ async getSequenceNumber() {
737
+ try {
738
+ const accInfo = await this._aptos.getAccountInfo({
739
+ accountAddress: this.account.accountAddress
740
+ });
741
+ return BigInt(accInfo.sequence_number);
742
+ } catch (error) {
743
+ console.error(
744
+ `Failed to get sequence number for ${this.account.accountAddress.toString()}:`,
745
+ error
746
+ );
747
+ throw error;
748
+ }
749
+ }
750
+ /**
751
+ * Returns information about the current state.
752
+ * Useful for debugging and monitoring.
753
+ */
754
+ getStatus() {
755
+ return {
756
+ pendingTransactions: this.currentNumber !== null && this.lastCommittedNumber !== null ? this.currentNumber - this.lastCommittedNumber : BigInt(0),
757
+ currentNumber: this.currentNumber,
758
+ lastCommittedNumber: this.lastCommittedNumber,
759
+ isLocked: this.isLocked,
760
+ queuedOperations: this.lockQueue.length
761
+ };
762
+ }
763
+ };
764
+
583
765
  // src/client.ts
584
766
  var getRandomId = () => (0, import_uuid.v4)();
585
767
  var Client = class _Client {
@@ -753,6 +935,7 @@ var Client = class _Client {
753
935
  this._apiKey = apiKey || generateApiKey();
754
936
  this._subscriptions = /* @__PURE__ */ new Map();
755
937
  this._serverUrl = url;
938
+ this._sequenceNumberManager = new AccountSequenceNumber(this._aptos, this._apiKey);
756
939
  this._ws = ws;
757
940
  if (this._ws) {
758
941
  this._ws.onmessage = async (msg) => {
@@ -823,12 +1006,11 @@ var Client = class _Client {
823
1006
  async setApiKey(apiKey) {
824
1007
  this._apiKey = apiKey;
825
1008
  this._apiKeySequenceNumber = await this.fetchApiKeySequenceNumber();
1009
+ this._sequenceNumberManager = new AccountSequenceNumber(this._aptos, this._apiKey);
1010
+ await this._sequenceNumberManager.initialize();
826
1011
  }
827
1012
  getApiKeySequenceNumber() {
828
- return this._apiKeySequenceNumber;
829
- }
830
- incrementSequenceNumber() {
831
- this._apiKeySequenceNumber++;
1013
+ return this._sequenceNumberManager.getSequenceNumber();
832
1014
  }
833
1015
  async fetchApiKeySequenceNumber() {
834
1016
  const accInfo = await this._aptos.getAccountInfo({
@@ -960,7 +1142,7 @@ var Client = class _Client {
960
1142
  return await this.submitSponsoredTransaction(tx, signature);
961
1143
  }
962
1144
  async placePerpLimitOrder(params) {
963
- console.log("start", (/* @__PURE__ */ new Date()).getMilliseconds());
1145
+ console.log("start");
964
1146
  const payload = (0, import_surf.createEntryPayload)(placePerpLimitOrder_default, {
965
1147
  function: "place_perp_limit_order",
966
1148
  functionArguments: [
@@ -973,22 +1155,35 @@ var Client = class _Client {
973
1155
  ],
974
1156
  typeArguments: []
975
1157
  });
976
- console.log("payload", (/* @__PURE__ */ new Date()).getMilliseconds());
1158
+ console.log("get sequence number");
1159
+ const sequenceNumber = await this.getApiKeySequenceNumber();
1160
+ console.log("sequence number", sequenceNumber);
977
1161
  const tx = await this._aptos.transaction.build.simple({
978
1162
  sender: this._apiKey.accountAddress,
979
- data: payload,
1163
+ data: {
1164
+ ...payload,
1165
+ abi: parseEntryFunctionAbi({
1166
+ moduleAbi: placePerpLimitOrder_default,
1167
+ functionName: "place_perp_limit_order",
1168
+ moduleAddress: "0x88dd5fbd381db9ad1566c8bbaec39a3d98906b3983a74bcafba70a09ae8f58f6",
1169
+ moduleName: "place_perp_limit_order"
1170
+ })
1171
+ },
980
1172
  withFeePayer: true,
981
1173
  options: {
982
- accountSequenceNumber: this.getApiKeySequenceNumber()
1174
+ accountSequenceNumber: sequenceNumber,
1175
+ // Now + 10 sec
1176
+ expireTimestamp: Date.now() + 10 * 1e3,
1177
+ gasUnitPrice: 100,
1178
+ maxGasAmount: 1e4
983
1179
  }
984
1180
  });
985
- this.incrementSequenceNumber();
986
- console.log("tx", (/* @__PURE__ */ new Date()).getMilliseconds());
1181
+ console.log("after build");
987
1182
  const signature = this._aptos.sign({
988
1183
  signer: this._apiKey,
989
1184
  transaction: tx
990
1185
  });
991
- console.log("signature", (/* @__PURE__ */ new Date()).getMilliseconds());
1186
+ console.log("after sign");
992
1187
  return await this.submitSponsoredTransaction(tx, signature);
993
1188
  }
994
1189
  async placePerpMarketOrder(params) {
@@ -1006,12 +1201,8 @@ var Client = class _Client {
1006
1201
  const tx = await this._aptos.transaction.build.simple({
1007
1202
  sender: this._apiKey.accountAddress,
1008
1203
  data: payload,
1009
- withFeePayer: true,
1010
- options: {
1011
- accountSequenceNumber: this.getApiKeySequenceNumber()
1012
- }
1204
+ withFeePayer: true
1013
1205
  });
1014
- this.incrementSequenceNumber();
1015
1206
  const signature = this._aptos.sign({
1016
1207
  signer: this._apiKey,
1017
1208
  transaction: tx
@@ -1161,6 +1352,30 @@ var Client = class _Client {
1161
1352
  }
1162
1353
  };
1163
1354
  var client_default = Client;
1355
+ function parseEntryFunctionAbi(args) {
1356
+ const { moduleAbi, moduleAddress, moduleName, functionName } = args;
1357
+ const functionAbi = moduleAbi.exposed_functions.find((func) => func.name === functionName);
1358
+ if (!functionAbi) {
1359
+ throw new Error(
1360
+ `Could not find entry function ABI for '${moduleAddress}::${moduleName}::${functionName}'`
1361
+ );
1362
+ }
1363
+ if (!functionAbi.is_entry) {
1364
+ throw new Error(
1365
+ `'${moduleAddress}::${moduleName}::${functionName}' is not an entry function`
1366
+ );
1367
+ }
1368
+ const numSigners = (0, import_ts_sdk2.findFirstNonSignerArg)(functionAbi);
1369
+ const params = [];
1370
+ for (let i = numSigners; i < functionAbi.params.length; i += 1) {
1371
+ params.push((0, import_ts_sdk2.parseTypeTag)(functionAbi.params[i], { allowGenerics: true }));
1372
+ }
1373
+ return {
1374
+ signers: numSigners,
1375
+ typeParameters: functionAbi.generic_type_params,
1376
+ parameters: params
1377
+ };
1378
+ }
1164
1379
 
1165
1380
  // src/testFaucet.ts
1166
1381
  var import_surf2 = require("@thalalabs/surf");
@@ -1519,6 +1734,8 @@ var TestFaucet = class _TestFaucet extends client_default {
1519
1734
  getRandomId,
1520
1735
  getTopicFromCommand,
1521
1736
  getTopicFromMessage,
1737
+ nowInMiliseconds,
1738
+ parseEntryFunctionAbi,
1522
1739
  sleep,
1523
1740
  toSystemValue
1524
1741
  });
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _aptos_labs_ts_sdk from '@aptos-labs/ts-sdk';
2
- import { Aptos, Account, AccountAuthenticator, SimpleTransaction } from '@aptos-labs/ts-sdk';
2
+ import { Account, Aptos, AccountAuthenticator, SimpleTransaction, MoveModule, EntryFunctionABI } from '@aptos-labs/ts-sdk';
3
3
  import * as _thalalabs_surf_build_types_core from '@thalalabs/surf/build/types/core';
4
4
  import * as _thalalabs_surf from '@thalalabs/surf';
5
5
  import WebSocket from 'isomorphic-ws';
@@ -589,6 +589,87 @@ declare enum Network {
589
589
  Devnet = "Devnet"
590
590
  }
591
591
 
592
+ /**
593
+ * Manages sequence numbers for Aptos blockchain transactions.
594
+ * Ensures proper transaction ordering and handles synchronization with the blockchain.
595
+ */
596
+ declare class AccountSequenceNumber {
597
+ private _aptos;
598
+ readonly account: Account;
599
+ private lastCommittedNumber;
600
+ private currentNumber;
601
+ private isLocked;
602
+ private lockQueue;
603
+ private readonly maxWaitTime;
604
+ private readonly maximumInFlight;
605
+ private readonly sleepTime;
606
+ private readonly warningTime;
607
+ /**
608
+ * Creates an instance of AccountSequenceNumber.
609
+ *
610
+ * @param aptos - The Aptos client instance
611
+ * @param account - The account associated with transactions
612
+ * @param options - Configuration options
613
+ */
614
+ constructor(aptos: Aptos, account: Account, options?: {
615
+ maxWaitTime?: number;
616
+ maximumInFlight?: number;
617
+ sleepTime?: number;
618
+ warningTime?: number;
619
+ });
620
+ /**
621
+ * Acquires the lock for synchronized access.
622
+ */
623
+ private acquireLock;
624
+ /**
625
+ * Releases the lock and processes the next queued operation if any.
626
+ */
627
+ private releaseLock;
628
+ /**
629
+ * Returns the next available sequence number for this account.
630
+ *
631
+ * @returns The next available sequence number or null if an error occurs
632
+ */
633
+ nextSequenceNumber(): Promise<bigint | null>;
634
+ /**
635
+ * Waits for pending transactions to be committed.
636
+ */
637
+ private waitForCommit;
638
+ /**
639
+ * Initializes this account with the sequence number on chain.
640
+ */
641
+ initialize(): Promise<void>;
642
+ /**
643
+ * Updates this account's sequence number with the one on-chain.
644
+ *
645
+ * @returns The on-chain sequence number for this account.
646
+ */
647
+ update(): Promise<bigint>;
648
+ /**
649
+ * Synchronizes the local sequence number with the sequence number on-chain.
650
+ * This method waits until all submitted transactions have been committed.
651
+ */
652
+ synchronize(): Promise<void>;
653
+ /**
654
+ * Gets the current sequence number from the blockchain.
655
+ *
656
+ * @returns The current sequence number
657
+ * @throws If unable to retrieve the account information
658
+ */
659
+ getSequenceNumber(): Promise<bigint>;
660
+ /**
661
+ * Returns information about the current state.
662
+ * Useful for debugging and monitoring.
663
+ */
664
+ getStatus(): {
665
+ pendingTransactions: bigint;
666
+ currentNumber: bigint | null;
667
+ lastCommittedNumber: bigint | null;
668
+ isLocked: boolean;
669
+ queuedOperations: number;
670
+ };
671
+ }
672
+
592
673
  declare const getRandomId: () => string;
593
674
  declare class Client {
594
675
  _aptos: Aptos;
@@ -598,6 +679,7 @@ declare class Client {
598
679
  _ws: WebSocket | undefined;
599
680
  _serverUrl: string;
600
681
  _subscriptions: Map<string, (data: WsMessage) => void>;
682
+ _sequenceNumberManager: AccountSequenceNumber;
601
683
  timeout: number;
602
684
  static init(connection: Aptos, apiKey?: Account, url?: string, enableWs?: boolean): Promise<Client>;
603
685
  constructor(connection: Aptos, url: string, ws?: WebSocket, apiKey?: Account);
@@ -605,8 +687,7 @@ declare class Client {
605
687
  sendWsMessage(message: WsCommand): Promise<WsMessage>;
606
688
  static create(connection: Aptos, apiKey?: Account, url?: string, enableWs?: boolean): Promise<Client>;
607
689
  setApiKey(apiKey: Account): Promise<void>;
608
- getApiKeySequenceNumber(): number;
609
- incrementSequenceNumber(): void;
690
+ getApiKeySequenceNumber(): Promise<bigint>;
610
691
  fetchApiKeySequenceNumber(): Promise<number>;
611
692
  createUser(params: CreateUserParams): Promise<{
612
693
  tx: _aptos_labs_ts_sdk.MultiAgentTransaction;
@@ -742,6 +823,13 @@ type WsPerpMarketUpdates = Extract<WsMessage, {
742
823
  type: 'OrderbookUpdate' | 'TradesUpdate';
743
824
  }>;
744
825
 
826
+ declare function parseEntryFunctionAbi(args: {
827
+ moduleAbi: MoveModule;
828
+ moduleAddress: string;
829
+ moduleName: string;
830
+ functionName: string;
831
+ }): EntryFunctionABI;
832
+
745
833
  declare const ExchangeProxies: {
746
834
  [key in Network]: string[];
747
835
  };
@@ -758,9 +846,10 @@ declare class TestFaucet extends Client {
758
846
  }
759
847
 
760
848
  declare const sleep: (ms: number) => Promise<unknown>;
849
+ declare const nowInMiliseconds: () => number;
761
850
  declare const toSystemValue: (value: string | number) => string;
762
851
  declare const generateApiKey: () => _aptos_labs_ts_sdk.Ed25519Account;
763
852
  declare const getTopicFromCommand: (data: WsCommand) => string;
764
853
  declare const getTopicFromMessage: (data: WsMessage) => string;
765
854
 
766
- export { type AddApiKey, type AddApiKeyParams, type Address, AdminEndpoints, type BalanceChange, BaseEndpoints, type Borrow, type BorrowLending, type CancelAllPerpOrdersParams, type CancelPerpOrdersParams, type CanceledPerpOrders, type ChartCandle, ChartInterval, Client, type Content, type CreateUserParams, type Deposit, type DepositToVaultParams, type DepositTokenParams, EndpointsV1, type ErrorResponse, type ExchangeConfig, ExchangeProxies, type Fees, type FundingCheckpoint, type FundingRate, GLOBAL_DENOMINATOR, type GetBorrowLendingDataResponse, type GetChartCandlesInRangeRequest, type GetChartCandlesInRangeResponse, type GetPerpMarketsDataRequest, type GetPerpMarketsDataResponse, type GetPerpOrderBookDataRequest, type GetPerpOrderBookDataResponse, type GetPerpRecentTradesRequest, type GetPerpRecentTradesResponse, type GetPerpUserFillsRequest, type GetPerpUserFillsResponse, type GetPerpUserOrdersRequest, type GetPerpUserOrdersResponse, type GetPerpetualMarketsConfigResponse, type GetPriceIndexesResponse, type GetTokensConfigResponse, type GetUserDataRequest, type GetUserDataResponse, type GetUsersByAddressRequest, type GetUsersByAddressResponse, type IGetChartCandlesInRange, type Lend, type LendTokenParams, type MarginStep, Network, type OracleUpdate, type OracleUpdates, type Order, type OrderFills, OrderSide, OrderStatus, OrderType, type OrderbookUpdate, type PaginationCursor, type PerpFill, type PerpMarketData, type PerpOrder, type PerpOrderBookData, type PerpPosition, type PerpTrade, type PerpetualMarketConfigEntry, PerpetualMarketStatus, type PlacePerpLimitOrder, type PlacePerpLimitOrderParams, type PlacePerpMarketOrder, type PlacePerpMarketOrderParams, type PriceIndex, type RedeemTokenParams, type Referral, type RemoveApiKey, type RemoveApiKeyParams, type RepayBorrow, type SetAlias, type SetAliasNameParams, type SetAutolend, type SetAutolendParams, Status, type StatusResponse, type SubmitSponsoredTransactionRequest, type SubmitSponsoredTransactionResponse, TestFaucet, type TimeResponse, type TokenConfigEntry, type Topic, type Trade, TradeRole, type TradesUpdate, type User, UserStatus, type UtilizationCurve, type VaultInvestment, type Withdraw, type WithdrawFromVaultParams, type WithdrawLend, type WsCommand, type WsFill, type WsMessage, type WsOracleUpdates, type WsPerpMarketUpdates, type WsUserUpdates, generateApiKey, getRandomId, getTopicFromCommand, getTopicFromMessage, sleep, toSystemValue };
855
+ export { type AddApiKey, type AddApiKeyParams, type Address, AdminEndpoints, type BalanceChange, BaseEndpoints, type Borrow, type BorrowLending, type CancelAllPerpOrdersParams, type CancelPerpOrdersParams, type CanceledPerpOrders, type ChartCandle, ChartInterval, Client, type Content, type CreateUserParams, type Deposit, type DepositToVaultParams, type DepositTokenParams, EndpointsV1, type ErrorResponse, type ExchangeConfig, ExchangeProxies, type Fees, type FundingCheckpoint, type FundingRate, GLOBAL_DENOMINATOR, type GetBorrowLendingDataResponse, type GetChartCandlesInRangeRequest, type GetChartCandlesInRangeResponse, type GetPerpMarketsDataRequest, type GetPerpMarketsDataResponse, type GetPerpOrderBookDataRequest, type GetPerpOrderBookDataResponse, type GetPerpRecentTradesRequest, type GetPerpRecentTradesResponse, type GetPerpUserFillsRequest, type GetPerpUserFillsResponse, type GetPerpUserOrdersRequest, type GetPerpUserOrdersResponse, type GetPerpetualMarketsConfigResponse, type GetPriceIndexesResponse, type GetTokensConfigResponse, type GetUserDataRequest, type GetUserDataResponse, type GetUsersByAddressRequest, type GetUsersByAddressResponse, type IGetChartCandlesInRange, type Lend, type LendTokenParams, type MarginStep, Network, type OracleUpdate, type OracleUpdates, type Order, type OrderFills, OrderSide, OrderStatus, OrderType, type OrderbookUpdate, type PaginationCursor, type PerpFill, type PerpMarketData, type PerpOrder, type PerpOrderBookData, type PerpPosition, type PerpTrade, type PerpetualMarketConfigEntry, PerpetualMarketStatus, type PlacePerpLimitOrder, type PlacePerpLimitOrderParams, type PlacePerpMarketOrder, type PlacePerpMarketOrderParams, type PriceIndex, type RedeemTokenParams, type Referral, type RemoveApiKey, type RemoveApiKeyParams, type RepayBorrow, type SetAlias, type SetAliasNameParams, type SetAutolend, type SetAutolendParams, Status, type StatusResponse, type SubmitSponsoredTransactionRequest, type SubmitSponsoredTransactionResponse, TestFaucet, type TimeResponse, type TokenConfigEntry, type Topic, type Trade, TradeRole, type TradesUpdate, type User, UserStatus, type UtilizationCurve, type VaultInvestment, type Withdraw, type WithdrawFromVaultParams, type WithdrawLend, type WsCommand, type WsFill, type WsMessage, type WsOracleUpdates, type WsPerpMarketUpdates, type WsUserUpdates, generateApiKey, getRandomId, getTopicFromCommand, getTopicFromMessage, nowInMiliseconds, parseEntryFunctionAbi, sleep, toSystemValue };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _aptos_labs_ts_sdk from '@aptos-labs/ts-sdk';
2
- import { Aptos, Account, AccountAuthenticator, SimpleTransaction } from '@aptos-labs/ts-sdk';
2
+ import { Account, Aptos, AccountAuthenticator, SimpleTransaction, MoveModule, EntryFunctionABI } from '@aptos-labs/ts-sdk';
3
3
  import * as _thalalabs_surf_build_types_core from '@thalalabs/surf/build/types/core';
4
4
  import * as _thalalabs_surf from '@thalalabs/surf';
5
5
  import WebSocket from 'isomorphic-ws';
@@ -589,6 +589,87 @@ declare enum Network {
589
589
  Devnet = "Devnet"
590
590
  }
591
591
 
592
+ /**
593
+ * Manages sequence numbers for Aptos blockchain transactions.
594
+ * Ensures proper transaction ordering and handles synchronization with the blockchain.
595
+ */
596
+ declare class AccountSequenceNumber {
597
+ private _aptos;
598
+ readonly account: Account;
599
+ private lastCommittedNumber;
600
+ private currentNumber;
601
+ private isLocked;
602
+ private lockQueue;
603
+ private readonly maxWaitTime;
604
+ private readonly maximumInFlight;
605
+ private readonly sleepTime;
606
+ private readonly warningTime;
607
+ /**
608
+ * Creates an instance of AccountSequenceNumber.
609
+ *
610
+ * @param aptos - The Aptos client instance
611
+ * @param account - The account associated with transactions
612
+ * @param options - Configuration options
613
+ */
614
+ constructor(aptos: Aptos, account: Account, options?: {
615
+ maxWaitTime?: number;
616
+ maximumInFlight?: number;
617
+ sleepTime?: number;
618
+ warningTime?: number;
619
+ });
620
+ /**
621
+ * Acquires the lock for synchronized access.
622
+ */
623
+ private acquireLock;
624
+ /**
625
+ * Releases the lock and processes the next queued operation if any.
626
+ */
627
+ private releaseLock;
628
+ /**
629
+ * Returns the next available sequence number for this account.
630
+ *
631
+ * @returns The next available sequence number or null if an error occurs
632
+ */
633
+ nextSequenceNumber(): Promise<bigint | null>;
634
+ /**
635
+ * Waits for pending transactions to be committed.
636
+ */
637
+ private waitForCommit;
638
+ /**
639
+ * Initializes this account with the sequence number on chain.
640
+ */
641
+ initialize(): Promise<void>;
642
+ /**
643
+ * Updates this account's sequence number with the one on-chain.
644
+ *
645
+ * @returns The on-chain sequence number for this account.
646
+ */
647
+ update(): Promise<bigint>;
648
+ /**
649
+ * Synchronizes the local sequence number with the sequence number on-chain.
650
+ * This method waits until all submitted transactions have been committed.
651
+ */
652
+ synchronize(): Promise<void>;
653
+ /**
654
+ * Gets the current sequence number from the blockchain.
655
+ *
656
+ * @returns The current sequence number
657
+ * @throws If unable to retrieve the account information
658
+ */
659
+ getSequenceNumber(): Promise<bigint>;
660
+ /**
661
+ * Returns information about the current state.
662
+ * Useful for debugging and monitoring.
663
+ */
664
+ getStatus(): {
665
+ pendingTransactions: bigint;
666
+ currentNumber: bigint | null;
667
+ lastCommittedNumber: bigint | null;
668
+ isLocked: boolean;
669
+ queuedOperations: number;
670
+ };
671
+ }
672
+
592
673
  declare const getRandomId: () => string;
593
674
  declare class Client {
594
675
  _aptos: Aptos;
@@ -598,6 +679,7 @@ declare class Client {
598
679
  _ws: WebSocket | undefined;
599
680
  _serverUrl: string;
600
681
  _subscriptions: Map<string, (data: WsMessage) => void>;
682
+ _sequenceNumberManager: AccountSequenceNumber;
601
683
  timeout: number;
602
684
  static init(connection: Aptos, apiKey?: Account, url?: string, enableWs?: boolean): Promise<Client>;
603
685
  constructor(connection: Aptos, url: string, ws?: WebSocket, apiKey?: Account);
@@ -605,8 +687,7 @@ declare class Client {
605
687
  sendWsMessage(message: WsCommand): Promise<WsMessage>;
606
688
  static create(connection: Aptos, apiKey?: Account, url?: string, enableWs?: boolean): Promise<Client>;
607
689
  setApiKey(apiKey: Account): Promise<void>;
608
- getApiKeySequenceNumber(): number;
609
- incrementSequenceNumber(): void;
690
+ getApiKeySequenceNumber(): Promise<bigint>;
610
691
  fetchApiKeySequenceNumber(): Promise<number>;
611
692
  createUser(params: CreateUserParams): Promise<{
612
693
  tx: _aptos_labs_ts_sdk.MultiAgentTransaction;
@@ -742,6 +823,13 @@ type WsPerpMarketUpdates = Extract<WsMessage, {
742
823
  type: 'OrderbookUpdate' | 'TradesUpdate';
743
824
  }>;
744
825
 
826
+ declare function parseEntryFunctionAbi(args: {
827
+ moduleAbi: MoveModule;
828
+ moduleAddress: string;
829
+ moduleName: string;
830
+ functionName: string;
831
+ }): EntryFunctionABI;
832
+
745
833
  declare const ExchangeProxies: {
746
834
  [key in Network]: string[];
747
835
  };
@@ -758,9 +846,10 @@ declare class TestFaucet extends Client {
758
846
  }
759
847
 
760
848
  declare const sleep: (ms: number) => Promise<unknown>;
849
+ declare const nowInMiliseconds: () => number;
761
850
  declare const toSystemValue: (value: string | number) => string;
762
851
  declare const generateApiKey: () => _aptos_labs_ts_sdk.Ed25519Account;
763
852
  declare const getTopicFromCommand: (data: WsCommand) => string;
764
853
  declare const getTopicFromMessage: (data: WsMessage) => string;
765
854
 
766
- export { type AddApiKey, type AddApiKeyParams, type Address, AdminEndpoints, type BalanceChange, BaseEndpoints, type Borrow, type BorrowLending, type CancelAllPerpOrdersParams, type CancelPerpOrdersParams, type CanceledPerpOrders, type ChartCandle, ChartInterval, Client, type Content, type CreateUserParams, type Deposit, type DepositToVaultParams, type DepositTokenParams, EndpointsV1, type ErrorResponse, type ExchangeConfig, ExchangeProxies, type Fees, type FundingCheckpoint, type FundingRate, GLOBAL_DENOMINATOR, type GetBorrowLendingDataResponse, type GetChartCandlesInRangeRequest, type GetChartCandlesInRangeResponse, type GetPerpMarketsDataRequest, type GetPerpMarketsDataResponse, type GetPerpOrderBookDataRequest, type GetPerpOrderBookDataResponse, type GetPerpRecentTradesRequest, type GetPerpRecentTradesResponse, type GetPerpUserFillsRequest, type GetPerpUserFillsResponse, type GetPerpUserOrdersRequest, type GetPerpUserOrdersResponse, type GetPerpetualMarketsConfigResponse, type GetPriceIndexesResponse, type GetTokensConfigResponse, type GetUserDataRequest, type GetUserDataResponse, type GetUsersByAddressRequest, type GetUsersByAddressResponse, type IGetChartCandlesInRange, type Lend, type LendTokenParams, type MarginStep, Network, type OracleUpdate, type OracleUpdates, type Order, type OrderFills, OrderSide, OrderStatus, OrderType, type OrderbookUpdate, type PaginationCursor, type PerpFill, type PerpMarketData, type PerpOrder, type PerpOrderBookData, type PerpPosition, type PerpTrade, type PerpetualMarketConfigEntry, PerpetualMarketStatus, type PlacePerpLimitOrder, type PlacePerpLimitOrderParams, type PlacePerpMarketOrder, type PlacePerpMarketOrderParams, type PriceIndex, type RedeemTokenParams, type Referral, type RemoveApiKey, type RemoveApiKeyParams, type RepayBorrow, type SetAlias, type SetAliasNameParams, type SetAutolend, type SetAutolendParams, Status, type StatusResponse, type SubmitSponsoredTransactionRequest, type SubmitSponsoredTransactionResponse, TestFaucet, type TimeResponse, type TokenConfigEntry, type Topic, type Trade, TradeRole, type TradesUpdate, type User, UserStatus, type UtilizationCurve, type VaultInvestment, type Withdraw, type WithdrawFromVaultParams, type WithdrawLend, type WsCommand, type WsFill, type WsMessage, type WsOracleUpdates, type WsPerpMarketUpdates, type WsUserUpdates, generateApiKey, getRandomId, getTopicFromCommand, getTopicFromMessage, sleep, toSystemValue };
855
+ export { type AddApiKey, type AddApiKeyParams, type Address, AdminEndpoints, type BalanceChange, BaseEndpoints, type Borrow, type BorrowLending, type CancelAllPerpOrdersParams, type CancelPerpOrdersParams, type CanceledPerpOrders, type ChartCandle, ChartInterval, Client, type Content, type CreateUserParams, type Deposit, type DepositToVaultParams, type DepositTokenParams, EndpointsV1, type ErrorResponse, type ExchangeConfig, ExchangeProxies, type Fees, type FundingCheckpoint, type FundingRate, GLOBAL_DENOMINATOR, type GetBorrowLendingDataResponse, type GetChartCandlesInRangeRequest, type GetChartCandlesInRangeResponse, type GetPerpMarketsDataRequest, type GetPerpMarketsDataResponse, type GetPerpOrderBookDataRequest, type GetPerpOrderBookDataResponse, type GetPerpRecentTradesRequest, type GetPerpRecentTradesResponse, type GetPerpUserFillsRequest, type GetPerpUserFillsResponse, type GetPerpUserOrdersRequest, type GetPerpUserOrdersResponse, type GetPerpetualMarketsConfigResponse, type GetPriceIndexesResponse, type GetTokensConfigResponse, type GetUserDataRequest, type GetUserDataResponse, type GetUsersByAddressRequest, type GetUsersByAddressResponse, type IGetChartCandlesInRange, type Lend, type LendTokenParams, type MarginStep, Network, type OracleUpdate, type OracleUpdates, type Order, type OrderFills, OrderSide, OrderStatus, OrderType, type OrderbookUpdate, type PaginationCursor, type PerpFill, type PerpMarketData, type PerpOrder, type PerpOrderBookData, type PerpPosition, type PerpTrade, type PerpetualMarketConfigEntry, PerpetualMarketStatus, type PlacePerpLimitOrder, type PlacePerpLimitOrderParams, type PlacePerpMarketOrder, type PlacePerpMarketOrderParams, type PriceIndex, type RedeemTokenParams, type Referral, type RemoveApiKey, type RemoveApiKeyParams, type RepayBorrow, type SetAlias, type SetAliasNameParams, type SetAutolend, type SetAutolendParams, Status, type StatusResponse, type SubmitSponsoredTransactionRequest, type SubmitSponsoredTransactionResponse, TestFaucet, type TimeResponse, type TokenConfigEntry, type Topic, type Trade, TradeRole, type TradesUpdate, type User, UserStatus, type UtilizationCurve, type VaultInvestment, type Withdraw, type WithdrawFromVaultParams, type WithdrawLend, type WsCommand, type WsFill, type WsMessage, type WsOracleUpdates, type WsPerpMarketUpdates, type WsUserUpdates, generateApiKey, getRandomId, getTopicFromCommand, getTopicFromMessage, nowInMiliseconds, parseEntryFunctionAbi, sleep, toSystemValue };
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  // src/client.ts
2
+ import {
3
+ findFirstNonSignerArg,
4
+ parseTypeTag
5
+ } from "@aptos-labs/ts-sdk";
2
6
  import { createEntryPayload, createSurfClient } from "@thalalabs/surf";
3
7
  import WebSocket from "isomorphic-ws";
4
8
  import { v4 as uuidv4 } from "uuid";
@@ -456,6 +460,7 @@ var GLOBAL_DENOMINATOR = 1e8;
456
460
  // src/utils.ts
457
461
  import { Decimal } from "decimal.js";
458
462
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
463
+ var nowInMiliseconds = () => Date.now();
459
464
  var toSystemValue = (value) => {
460
465
  return new Decimal(value).mul(new Decimal(GLOBAL_DENOMINATOR)).toString();
461
466
  };
@@ -523,6 +528,184 @@ var getTopicFromMessage = (data) => {
523
528
  }
524
529
  };
525
530
 
531
+ // src/sequenceNumberManager.ts
532
+ var AccountSequenceNumber = class {
533
+ /**
534
+ * Creates an instance of AccountSequenceNumber.
535
+ *
536
+ * @param aptos - The Aptos client instance
537
+ * @param account - The account associated with transactions
538
+ * @param options - Configuration options
539
+ */
540
+ constructor(aptos, account, options = {}) {
541
+ // Sequence number on chain
542
+ this.lastCommittedNumber = null;
543
+ // Local sequence number (next to be used)
544
+ this.currentNumber = null;
545
+ // Use a proper mutex implementation instead of a boolean flag
546
+ this.isLocked = false;
547
+ this.lockQueue = [];
548
+ this._aptos = aptos;
549
+ this.account = account;
550
+ this.maxWaitTime = options.maxWaitTime ?? 1e4;
551
+ this.maximumInFlight = options.maximumInFlight ?? 100;
552
+ this.sleepTime = options.sleepTime ?? 10;
553
+ this.warningTime = options.warningTime ?? 3e4;
554
+ }
555
+ /**
556
+ * Acquires the lock for synchronized access.
557
+ */
558
+ async acquireLock() {
559
+ if (!this.isLocked) {
560
+ this.isLocked = true;
561
+ return;
562
+ }
563
+ return new Promise((resolve) => {
564
+ this.lockQueue.push(resolve);
565
+ });
566
+ }
567
+ /**
568
+ * Releases the lock and processes the next queued operation if any.
569
+ */
570
+ releaseLock() {
571
+ if (this.lockQueue.length > 0) {
572
+ const nextResolve = this.lockQueue.shift();
573
+ if (nextResolve) {
574
+ nextResolve();
575
+ }
576
+ } else {
577
+ this.isLocked = false;
578
+ }
579
+ }
580
+ /**
581
+ * Returns the next available sequence number for this account.
582
+ *
583
+ * @returns The next available sequence number or null if an error occurs
584
+ */
585
+ async nextSequenceNumber() {
586
+ await this.acquireLock();
587
+ try {
588
+ if (this.lastCommittedNumber === null || this.currentNumber === null) {
589
+ await this.initialize();
590
+ }
591
+ if (this.currentNumber - this.lastCommittedNumber >= this.maximumInFlight) {
592
+ await this.waitForCommit();
593
+ }
594
+ const nextNumber = this.currentNumber;
595
+ this.currentNumber = this.currentNumber + BigInt(1);
596
+ return nextNumber;
597
+ } catch (e) {
598
+ console.error("Error getting next sequence number:", e);
599
+ return null;
600
+ } finally {
601
+ this.releaseLock();
602
+ }
603
+ }
604
+ /**
605
+ * Waits for pending transactions to be committed.
606
+ */
607
+ async waitForCommit() {
608
+ await this.update();
609
+ const startTime = nowInMiliseconds();
610
+ while (this.currentNumber - this.lastCommittedNumber >= this.maximumInFlight) {
611
+ const elapsed = nowInMiliseconds() - startTime;
612
+ if (elapsed > this.maxWaitTime) {
613
+ console.warn(
614
+ `Waited over ${this.maxWaitTime / 1e3} seconds for a transaction to commit, re-syncing ${this.account.accountAddress.toString()}`
615
+ );
616
+ await this.initialize();
617
+ break;
618
+ }
619
+ if (elapsed > this.warningTime && elapsed % 5e3 < this.sleepTime) {
620
+ console.warn(
621
+ `Still waiting for transactions to commit after ${elapsed / 1e3} seconds for account ${this.account.accountAddress.toString()}`
622
+ );
623
+ }
624
+ await sleep(this.sleepTime);
625
+ await this.update();
626
+ }
627
+ }
628
+ /**
629
+ * Initializes this account with the sequence number on chain.
630
+ */
631
+ async initialize() {
632
+ const sequenceNumber = await this.getSequenceNumber();
633
+ this.currentNumber = sequenceNumber;
634
+ this.lastCommittedNumber = sequenceNumber;
635
+ }
636
+ /**
637
+ * Updates this account's sequence number with the one on-chain.
638
+ *
639
+ * @returns The on-chain sequence number for this account.
640
+ */
641
+ async update() {
642
+ const sequenceNumber = await this.getSequenceNumber();
643
+ this.lastCommittedNumber = sequenceNumber;
644
+ return this.lastCommittedNumber;
645
+ }
646
+ /**
647
+ * Synchronizes the local sequence number with the sequence number on-chain.
648
+ * This method waits until all submitted transactions have been committed.
649
+ */
650
+ async synchronize() {
651
+ if (this.lastCommittedNumber === this.currentNumber) return;
652
+ await this.acquireLock();
653
+ try {
654
+ await this.update();
655
+ const startTime = nowInMiliseconds();
656
+ while (this.lastCommittedNumber !== this.currentNumber) {
657
+ const elapsed = nowInMiliseconds() - startTime;
658
+ if (elapsed > this.maxWaitTime) {
659
+ console.warn(
660
+ `Waited over ${this.maxWaitTime / 1e3} seconds for all transactions to commit, re-syncing ${this.account.accountAddress.toString()}`
661
+ );
662
+ await this.initialize();
663
+ break;
664
+ }
665
+ await sleep(this.sleepTime);
666
+ await this.update();
667
+ }
668
+ } catch (e) {
669
+ console.error("Error synchronizing account sequence number:", e);
670
+ } finally {
671
+ this.releaseLock();
672
+ }
673
+ }
674
+ /**
675
+ * Gets the current sequence number from the blockchain.
676
+ *
677
+ * @returns The current sequence number
678
+ * @throws If unable to retrieve the account information
679
+ */
680
+ async getSequenceNumber() {
681
+ try {
682
+ const accInfo = await this._aptos.getAccountInfo({
683
+ accountAddress: this.account.accountAddress
684
+ });
685
+ return BigInt(accInfo.sequence_number);
686
+ } catch (error) {
687
+ console.error(
688
+ `Failed to get sequence number for ${this.account.accountAddress.toString()}:`,
689
+ error
690
+ );
691
+ throw error;
692
+ }
693
+ }
694
+ /**
695
+ * Returns information about the current state.
696
+ * Useful for debugging and monitoring.
697
+ */
698
+ getStatus() {
699
+ return {
700
+ pendingTransactions: this.currentNumber !== null && this.lastCommittedNumber !== null ? this.currentNumber - this.lastCommittedNumber : BigInt(0),
701
+ currentNumber: this.currentNumber,
702
+ lastCommittedNumber: this.lastCommittedNumber,
703
+ isLocked: this.isLocked,
704
+ queuedOperations: this.lockQueue.length
705
+ };
706
+ }
707
+ };
708
+
526
709
  // src/client.ts
527
710
  var getRandomId = () => uuidv4();
528
711
  var Client = class _Client {
@@ -696,6 +879,7 @@ var Client = class _Client {
696
879
  this._apiKey = apiKey || generateApiKey();
697
880
  this._subscriptions = /* @__PURE__ */ new Map();
698
881
  this._serverUrl = url;
882
+ this._sequenceNumberManager = new AccountSequenceNumber(this._aptos, this._apiKey);
699
883
  this._ws = ws;
700
884
  if (this._ws) {
701
885
  this._ws.onmessage = async (msg) => {
@@ -766,12 +950,11 @@ var Client = class _Client {
766
950
  async setApiKey(apiKey) {
767
951
  this._apiKey = apiKey;
768
952
  this._apiKeySequenceNumber = await this.fetchApiKeySequenceNumber();
953
+ this._sequenceNumberManager = new AccountSequenceNumber(this._aptos, this._apiKey);
954
+ await this._sequenceNumberManager.initialize();
769
955
  }
770
956
  getApiKeySequenceNumber() {
771
- return this._apiKeySequenceNumber;
772
- }
773
- incrementSequenceNumber() {
774
- this._apiKeySequenceNumber++;
957
+ return this._sequenceNumberManager.getSequenceNumber();
775
958
  }
776
959
  async fetchApiKeySequenceNumber() {
777
960
  const accInfo = await this._aptos.getAccountInfo({
@@ -903,7 +1086,7 @@ var Client = class _Client {
903
1086
  return await this.submitSponsoredTransaction(tx, signature);
904
1087
  }
905
1088
  async placePerpLimitOrder(params) {
906
- console.log("start", (/* @__PURE__ */ new Date()).getMilliseconds());
1089
+ console.log("start");
907
1090
  const payload = createEntryPayload(placePerpLimitOrder_default, {
908
1091
  function: "place_perp_limit_order",
909
1092
  functionArguments: [
@@ -916,22 +1099,35 @@ var Client = class _Client {
916
1099
  ],
917
1100
  typeArguments: []
918
1101
  });
919
- console.log("payload", (/* @__PURE__ */ new Date()).getMilliseconds());
1102
+ console.log("get sequence number");
1103
+ const sequenceNumber = await this.getApiKeySequenceNumber();
1104
+ console.log("sequence number", sequenceNumber);
920
1105
  const tx = await this._aptos.transaction.build.simple({
921
1106
  sender: this._apiKey.accountAddress,
922
- data: payload,
1107
+ data: {
1108
+ ...payload,
1109
+ abi: parseEntryFunctionAbi({
1110
+ moduleAbi: placePerpLimitOrder_default,
1111
+ functionName: "place_perp_limit_order",
1112
+ moduleAddress: "0x88dd5fbd381db9ad1566c8bbaec39a3d98906b3983a74bcafba70a09ae8f58f6",
1113
+ moduleName: "place_perp_limit_order"
1114
+ })
1115
+ },
923
1116
  withFeePayer: true,
924
1117
  options: {
925
- accountSequenceNumber: this.getApiKeySequenceNumber()
1118
+ accountSequenceNumber: sequenceNumber,
1119
+ // Now + 10 sec
1120
+ expireTimestamp: Date.now() + 10 * 1e3,
1121
+ gasUnitPrice: 100,
1122
+ maxGasAmount: 1e4
926
1123
  }
927
1124
  });
928
- this.incrementSequenceNumber();
929
- console.log("tx", (/* @__PURE__ */ new Date()).getMilliseconds());
1125
+ console.log("after build");
930
1126
  const signature = this._aptos.sign({
931
1127
  signer: this._apiKey,
932
1128
  transaction: tx
933
1129
  });
934
- console.log("signature", (/* @__PURE__ */ new Date()).getMilliseconds());
1130
+ console.log("after sign");
935
1131
  return await this.submitSponsoredTransaction(tx, signature);
936
1132
  }
937
1133
  async placePerpMarketOrder(params) {
@@ -949,12 +1145,8 @@ var Client = class _Client {
949
1145
  const tx = await this._aptos.transaction.build.simple({
950
1146
  sender: this._apiKey.accountAddress,
951
1147
  data: payload,
952
- withFeePayer: true,
953
- options: {
954
- accountSequenceNumber: this.getApiKeySequenceNumber()
955
- }
1148
+ withFeePayer: true
956
1149
  });
957
- this.incrementSequenceNumber();
958
1150
  const signature = this._aptos.sign({
959
1151
  signer: this._apiKey,
960
1152
  transaction: tx
@@ -1104,6 +1296,30 @@ var Client = class _Client {
1104
1296
  }
1105
1297
  };
1106
1298
  var client_default = Client;
1299
+ function parseEntryFunctionAbi(args) {
1300
+ const { moduleAbi, moduleAddress, moduleName, functionName } = args;
1301
+ const functionAbi = moduleAbi.exposed_functions.find((func) => func.name === functionName);
1302
+ if (!functionAbi) {
1303
+ throw new Error(
1304
+ `Could not find entry function ABI for '${moduleAddress}::${moduleName}::${functionName}'`
1305
+ );
1306
+ }
1307
+ if (!functionAbi.is_entry) {
1308
+ throw new Error(
1309
+ `'${moduleAddress}::${moduleName}::${functionName}' is not an entry function`
1310
+ );
1311
+ }
1312
+ const numSigners = findFirstNonSignerArg(functionAbi);
1313
+ const params = [];
1314
+ for (let i = numSigners; i < functionAbi.params.length; i += 1) {
1315
+ params.push(parseTypeTag(functionAbi.params[i], { allowGenerics: true }));
1316
+ }
1317
+ return {
1318
+ signers: numSigners,
1319
+ typeParameters: functionAbi.generic_type_params,
1320
+ parameters: params
1321
+ };
1322
+ }
1107
1323
 
1108
1324
  // src/testFaucet.ts
1109
1325
  import { createEntryPayload as createEntryPayload2 } from "@thalalabs/surf";
@@ -1461,6 +1677,8 @@ export {
1461
1677
  getRandomId,
1462
1678
  getTopicFromCommand,
1463
1679
  getTopicFromMessage,
1680
+ nowInMiliseconds,
1681
+ parseEntryFunctionAbi,
1464
1682
  sleep,
1465
1683
  toSystemValue
1466
1684
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nightlylabs/dex-sdk",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -38,7 +38,7 @@
38
38
  "license": "ISC",
39
39
  "packageManager": "pnpm@9.3.0+sha512.ee7b93e0c2bd11409c6424f92b866f31d3ea1bef5fbe47d3c7500cdc3c9668833d2e55681ad66df5b640c61fa9dc25d546efa54d76d7f8bf54b13614ac293631",
40
40
  "dependencies": {
41
- "@aptos-labs/ts-sdk": "^1.33.2",
41
+ "@aptos-labs/ts-sdk": "^1.35.0",
42
42
  "@thalalabs/surf": "^1.8.1",
43
43
  "decimal.js": "^10.5.0",
44
44
  "isomorphic-ws": "^5.0.0",