@bluefin-exchange/pro-sdk 2.0.0-beta.0 → 2.0.0-beta.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.
Files changed (38) hide show
  1. package/README.md +2 -3
  2. package/dist/esm/index.js +1 -1
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/src/api.js +609 -810
  5. package/dist/esm/src/api.js.map +1 -1
  6. package/dist/esm/src/base.js +5 -2
  7. package/dist/esm/src/base.js.map +1 -1
  8. package/dist/esm/src/common.js +23 -39
  9. package/dist/esm/src/common.js.map +1 -1
  10. package/dist/esm/src/configuration.js +62 -2
  11. package/dist/esm/src/configuration.js.map +1 -1
  12. package/dist/esm/src/index.js +6 -6
  13. package/dist/esm/src/index.js.map +1 -1
  14. package/dist/esm/src/request-signer.js +61 -81
  15. package/dist/esm/src/request-signer.js.map +1 -1
  16. package/dist/esm/src/sdk.js +529 -570
  17. package/dist/esm/src/sdk.js.map +1 -1
  18. package/dist/esm/src/websocket.js +69 -85
  19. package/dist/esm/src/websocket.js.map +1 -1
  20. package/dist/types/index.d.ts +1 -1
  21. package/dist/types/index.d.ts.map +1 -1
  22. package/dist/types/src/api.d.ts +7 -7
  23. package/dist/types/src/api.d.ts.map +1 -1
  24. package/dist/types/src/base.d.ts +1 -1
  25. package/dist/types/src/base.d.ts.map +1 -1
  26. package/dist/types/src/common.d.ts +2 -2
  27. package/dist/types/src/common.d.ts.map +1 -1
  28. package/dist/types/src/index.d.ts +6 -6
  29. package/dist/types/src/index.d.ts.map +1 -1
  30. package/dist/types/src/request-signer.d.ts +3 -2
  31. package/dist/types/src/request-signer.d.ts.map +1 -1
  32. package/dist/types/src/sdk.d.ts +9 -9
  33. package/dist/types/src/sdk.d.ts.map +1 -1
  34. package/package.json +6 -7
  35. package/dist/esm/example.js +0 -276
  36. package/dist/esm/example.js.map +0 -1
  37. package/dist/types/example.d.ts +0 -2
  38. package/dist/types/example.d.ts.map +0 -1
@@ -1,20 +1,9 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var _a;
11
- import { AccountDataApi, AuthApi, ExchangeApi, TradeApi, AdjustMarginOperation, RewardsApi, } from './api';
12
- import { Configuration } from './configuration';
1
+ import { AccountDataApi, AuthApi, ExchangeApi, TradeApi, AdjustMarginOperation, RewardsApi, } from './api.js';
2
+ import { Configuration } from './configuration.js';
13
3
  import { WebSocket } from 'ws';
14
- import { TxBuilder } from '@firefly-exchange/library-sui/v3';
15
- import { CoinUtils, TransactionBlock, Ed25519Keypair, decodeSuiPrivateKey, SuiBlocks, } from '@firefly-exchange/library-sui';
16
- // RewardsDistributorInteractor for reward claiming
17
- import { RewardsDistributorInteractor } from '@firefly-exchange/library-sui/index';
4
+ import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
5
+ import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
6
+ import { Transaction as TransactionBlock } from '@mysten/sui/transactions';
18
7
  import { toHex } from '@mysten/bcs';
19
8
  import globalAxios from 'axios';
20
9
  // Keep HTTP/2 as default in Node.js. Consumers can opt out with
@@ -22,7 +11,7 @@ import globalAxios from 'axios';
22
11
  if (typeof process !== 'undefined' &&
23
12
  process.versions &&
24
13
  process.versions.node) {
25
- const requestedHttpVersion = Number.parseInt((_a = process.env.BLUEFIN_SDK_HTTP_VERSION) !== null && _a !== void 0 ? _a : '2', 10);
14
+ const requestedHttpVersion = Number.parseInt(process.env.BLUEFIN_SDK_HTTP_VERSION ?? '2', 10);
26
15
  globalAxios.defaults.httpVersion = requestedHttpVersion === 2 ? 2 : 1;
27
16
  }
28
17
  const environmentConfig = {
@@ -48,6 +37,15 @@ const environmentConfig = {
48
37
  accountWsHost: 'wss://stream.api.sui-dev.bluefin.io/ws/account',
49
38
  },
50
39
  };
40
+ async function loadLibrarySuiRoot() {
41
+ return await import('@firefly-exchange/library-sui');
42
+ }
43
+ async function loadLibrarySuiV3() {
44
+ return await import('@firefly-exchange/library-sui/v3');
45
+ }
46
+ async function loadRewardsDistributorInteractor() {
47
+ return await import('@firefly-exchange/library-sui/index');
48
+ }
51
49
  var Services;
52
50
  (function (Services) {
53
51
  Services[Services["Account"] = 0] = "Account";
@@ -59,52 +57,60 @@ var Services;
59
57
  Services[Services["AccountWebsocket"] = 6] = "AccountWebsocket";
60
58
  })(Services || (Services = {}));
61
59
  export class BluefinProSdk {
60
+ bfSigner;
61
+ environment;
62
+ static TOKEN_REFRESH_THRESHOLD_PERCENTAGE = 0.8;
63
+ configs = {};
64
+ exchangeDataApi;
65
+ rewardsDataApi;
66
+ accountDataApi;
67
+ tradeApi;
68
+ authApi;
69
+ initializeOptions;
70
+ tokenResponse;
71
+ tokenSetAtSeconds;
72
+ isConnected;
73
+ updateTokenTimeout;
74
+ contractsConfig;
75
+ assets;
76
+ txBuilder;
77
+ currentAccountAddress;
78
+ disableLoginPromptOnLogout;
79
+ onLogout;
80
+ onAccessTokenUpdate;
81
+ isRefreshing;
82
+ refreshTokenPromise;
83
+ visibilityChangeHandler;
84
+ onlineHandler;
85
+ offlineHandler;
86
+ timeOffsetMs;
87
+ suiClient;
62
88
  constructor(bfSigner, environment = 'mainnet', suiClient, opts) {
63
- var _a, _b, _c, _d, _e, _f;
64
89
  this.bfSigner = bfSigner;
65
90
  this.environment = environment;
66
- this.configs = {};
67
- /**
68
- * @description
69
- * build gasless transaction payload bytes
70
- * @param tx transcation block
71
- * @returns string
72
- * */
73
- this.buildGaslessTxPayloadBytes = (txb) => __awaiter(this, void 0, void 0, function* () {
74
- try {
75
- return yield SuiBlocks.buildGaslessTxPayloadBytes(txb, this.suiClient);
76
- }
77
- catch (error) {
78
- throw new Error(error instanceof Error
79
- ? error.message
80
- : 'Build gasless tx payload bytes failed');
81
- }
82
- });
83
- // SuiJsonRpcClient and ClientWithCoreApi are structurally compatible
84
- // for all library-sui operations; cast once at the boundary.
85
91
  this.suiClient = suiClient;
86
- this.currentAccountAddress = opts === null || opts === void 0 ? void 0 : opts.currentAccountAddress;
92
+ this.currentAccountAddress = opts?.currentAccountAddress;
87
93
  this.isConnected = false;
88
94
  this.updateTokenTimeout = null;
89
95
  this.contractsConfig = undefined;
90
96
  this.tokenResponse = null;
91
97
  this.tokenSetAtSeconds = null;
92
- this.disableLoginPromptOnLogout = (_a = opts === null || opts === void 0 ? void 0 : opts.disableLoginPromptOnLogout) !== null && _a !== void 0 ? _a : false;
93
- this.onLogout = opts === null || opts === void 0 ? void 0 : opts.onLogout;
94
- this.onAccessTokenUpdate = opts === null || opts === void 0 ? void 0 : opts.onAccessTokenUpdate;
98
+ this.disableLoginPromptOnLogout = opts?.disableLoginPromptOnLogout ?? false;
99
+ this.onLogout = opts?.onLogout;
100
+ this.onAccessTokenUpdate = opts?.onAccessTokenUpdate;
95
101
  this.isRefreshing = false;
96
102
  this.refreshTokenPromise = null;
97
103
  this.visibilityChangeHandler = undefined;
98
104
  this.onlineHandler = undefined;
99
105
  this.offlineHandler = undefined;
100
106
  // Initialize time offset based on provided currentTimeMs
101
- if ((opts === null || opts === void 0 ? void 0 : opts.currentTimeMs) !== undefined) {
107
+ if (opts?.currentTimeMs !== undefined) {
102
108
  this.timeOffsetMs = opts.currentTimeMs - Date.now();
103
109
  }
104
110
  else {
105
111
  this.timeOffsetMs = 0;
106
112
  }
107
- if ((opts === null || opts === void 0 ? void 0 : opts.refreshToken) && (opts === null || opts === void 0 ? void 0 : opts.refreshTokenValidForSeconds)) {
113
+ if (opts?.refreshToken && opts?.refreshTokenValidForSeconds) {
108
114
  this.tokenResponse = {
109
115
  accessToken: '',
110
116
  accessTokenValidForSeconds: 0,
@@ -116,11 +122,11 @@ export class BluefinProSdk {
116
122
  }
117
123
  const defaultConfig = environmentConfig[this.environment];
118
124
  const basePaths = {
119
- authHost: (_b = opts === null || opts === void 0 ? void 0 : opts.authHost) !== null && _b !== void 0 ? _b : defaultConfig.authHost,
120
- apiHost: (_c = opts === null || opts === void 0 ? void 0 : opts.apiHost) !== null && _c !== void 0 ? _c : defaultConfig.apiHost,
121
- tradeHost: (_d = opts === null || opts === void 0 ? void 0 : opts.tradeHost) !== null && _d !== void 0 ? _d : defaultConfig.tradeHost,
122
- marketWsHost: (_e = opts === null || opts === void 0 ? void 0 : opts.marketWsHost) !== null && _e !== void 0 ? _e : defaultConfig.marketWsHost,
123
- accountWsHost: (_f = opts === null || opts === void 0 ? void 0 : opts.accountWsHost) !== null && _f !== void 0 ? _f : defaultConfig.accountWsHost,
125
+ authHost: opts?.authHost ?? defaultConfig.authHost,
126
+ apiHost: opts?.apiHost ?? defaultConfig.apiHost,
127
+ tradeHost: opts?.tradeHost ?? defaultConfig.tradeHost,
128
+ marketWsHost: opts?.marketWsHost ?? defaultConfig.marketWsHost,
129
+ accountWsHost: opts?.accountWsHost ?? defaultConfig.accountWsHost,
124
130
  };
125
131
  const authApiConfig = new Configuration({
126
132
  basePath: basePaths.authHost,
@@ -184,8 +190,7 @@ export class BluefinProSdk {
184
190
  this.timeOffsetMs = currentTimeMs - Date.now();
185
191
  }
186
192
  isRefreshTokenValid() {
187
- var _a;
188
- if (!((_a = this.tokenResponse) === null || _a === void 0 ? void 0 : _a.refreshToken) || !this.tokenSetAtSeconds) {
193
+ if (!this.tokenResponse?.refreshToken || !this.tokenSetAtSeconds) {
189
194
  return false;
190
195
  }
191
196
  const currentTimeSeconds = Date.now() / 1000;
@@ -194,8 +199,7 @@ export class BluefinProSdk {
194
199
  return currentTimeSeconds < refreshTokenExpiryTime - 60;
195
200
  }
196
201
  isAccessTokenExpired() {
197
- var _a;
198
- if (!((_a = this.tokenResponse) === null || _a === void 0 ? void 0 : _a.accessToken) || !this.tokenSetAtSeconds) {
202
+ if (!this.tokenResponse?.accessToken || !this.tokenSetAtSeconds) {
199
203
  return true;
200
204
  }
201
205
  const currentTimeSeconds = Date.now() / 1000;
@@ -206,62 +210,53 @@ export class BluefinProSdk {
206
210
  // Token is considered "expired" if we've passed the 80% lifetime mark
207
211
  return currentTimeSeconds >= refreshAtSeconds;
208
212
  }
209
- initializeTxBuilder() {
210
- return __awaiter(this, void 0, void 0, function* () {
211
- var _a, _b, _c, _d, _e, _f, _g, _h;
212
- this.txBuilder = new TxBuilder({
213
- AdminCap: '',
214
- ExternalDataStore: ((_a = this.contractsConfig) === null || _a === void 0 ? void 0 : _a.edsId) || '',
215
- InternalDataStore: ((_b = this.contractsConfig) === null || _b === void 0 ? void 0 : _b.idsId) || '',
216
- Operators: {
217
- admin: ((_c = this.contractsConfig) === null || _c === void 0 ? void 0 : _c.operators.admin) || '',
218
- fee: ((_d = this.contractsConfig) === null || _d === void 0 ? void 0 : _d.operators.fee) || '',
219
- funding: ((_e = this.contractsConfig) === null || _e === void 0 ? void 0 : _e.operators.funding) || '',
220
- pruning: '',
221
- sequencer: ((_f = this.contractsConfig) === null || _f === void 0 ? void 0 : _f.operators.sequencer) || '',
222
- },
223
- Package: ((_g = this.contractsConfig) === null || _g === void 0 ? void 0 : _g.currentContractAddress) || '',
224
- Perpetuals: {},
225
- SupportedAssets: ((_h = this.assets) === null || _h === void 0 ? void 0 : _h.reduce((agg, x) => {
226
- agg[x.symbol] = Object.assign(Object.assign({}, x), { coinType: x.assetType });
227
- return agg;
228
- }, {})) || {},
229
- TreasuryCap: '',
230
- UpgradeCap: '',
231
- });
232
- });
233
- }
234
- initialize(options) {
235
- return __awaiter(this, void 0, void 0, function* () {
236
- this.initializeOptions = options;
237
- yield this.setContractsConfig();
238
- yield this.initializeTxBuilder();
239
- yield this.loginAndUpdateToken();
240
- this.setupVisibilityChangeListener();
241
- this.setupNetworkChangeListener();
242
- });
243
- }
244
- setContractsConfig() {
245
- return __awaiter(this, void 0, void 0, function* () {
246
- const response = yield this.exchangeDataApi.getExchangeInfo();
247
- this.contractsConfig = response.data.contractsConfig;
248
- this.assets = response.data.assets;
249
- });
250
- }
251
- loginAndUpdateToken() {
252
- return __awaiter(this, void 0, void 0, function* () {
253
- var _a;
254
- yield this.login();
255
- // Safety check - if login failed or logout was called, tokenResponse might be null
256
- if (!this.tokenResponse) {
257
- throw new Error('Login failed - no token response available');
258
- }
259
- this.isConnected = true;
260
- // Notify about token refresh
261
- (_a = this.onAccessTokenUpdate) === null || _a === void 0 ? void 0 : _a.call(this, this.tokenResponse.accessToken);
262
- // Schedule the next token refresh
263
- this.scheduleTokenRefresh();
264
- });
213
+ async initializeTxBuilder() {
214
+ const { TxBuilder } = await loadLibrarySuiV3();
215
+ this.txBuilder = new TxBuilder({
216
+ AdminCap: '',
217
+ ExternalDataStore: this.contractsConfig?.edsId || '',
218
+ InternalDataStore: this.contractsConfig?.idsId || '',
219
+ Operators: {
220
+ admin: this.contractsConfig?.operators.admin || '',
221
+ fee: this.contractsConfig?.operators.fee || '',
222
+ funding: this.contractsConfig?.operators.funding || '',
223
+ pruning: '',
224
+ sequencer: this.contractsConfig?.operators.sequencer || '',
225
+ },
226
+ Package: this.contractsConfig?.currentContractAddress || '',
227
+ Perpetuals: {},
228
+ SupportedAssets: this.assets?.reduce((agg, x) => {
229
+ agg[x.symbol] = { ...x, coinType: x.assetType };
230
+ return agg;
231
+ }, {}) || {},
232
+ TreasuryCap: '',
233
+ UpgradeCap: '',
234
+ });
235
+ }
236
+ async initialize(options) {
237
+ this.initializeOptions = options;
238
+ await this.setContractsConfig();
239
+ await this.initializeTxBuilder();
240
+ await this.loginAndUpdateToken();
241
+ this.setupVisibilityChangeListener();
242
+ this.setupNetworkChangeListener();
243
+ }
244
+ async setContractsConfig() {
245
+ const response = await this.exchangeDataApi.getExchangeInfo();
246
+ this.contractsConfig = response.data.contractsConfig;
247
+ this.assets = response.data.assets;
248
+ }
249
+ async loginAndUpdateToken() {
250
+ await this.login();
251
+ // Safety check - if login failed or logout was called, tokenResponse might be null
252
+ if (!this.tokenResponse) {
253
+ throw new Error('Login failed - no token response available');
254
+ }
255
+ this.isConnected = true;
256
+ // Notify about token refresh
257
+ this.onAccessTokenUpdate?.(this.tokenResponse.accessToken);
258
+ // Schedule the next token refresh
259
+ this.scheduleTokenRefresh();
265
260
  }
266
261
  scheduleTokenRefresh() {
267
262
  // Clear any existing timeout
@@ -304,22 +299,18 @@ export class BluefinProSdk {
304
299
  window.addEventListener('offline', this.handleOffline);
305
300
  }
306
301
  }
307
- handleVisible() {
308
- return __awaiter(this, void 0, void 0, function* () {
309
- if (!this.tokenResponse || !this.tokenSetAtSeconds) {
310
- return;
311
- }
312
- this.refreshToken();
313
- });
302
+ async handleVisible() {
303
+ if (!this.tokenResponse || !this.tokenSetAtSeconds) {
304
+ return;
305
+ }
306
+ this.refreshToken();
314
307
  }
315
- handleOnline() {
316
- return __awaiter(this, void 0, void 0, function* () {
317
- if (!this.isConnected || !this.tokenResponse || !this.tokenSetAtSeconds) {
318
- return;
319
- }
320
- console.log('Network reconnected, resuming token refresh and checking token status');
321
- this.refreshToken(true);
322
- });
308
+ async handleOnline() {
309
+ if (!this.isConnected || !this.tokenResponse || !this.tokenSetAtSeconds) {
310
+ return;
311
+ }
312
+ console.log('Network reconnected, resuming token refresh and checking token status');
313
+ this.refreshToken(true);
323
314
  }
324
315
  handleOffline() {
325
316
  if (this.updateTokenTimeout) {
@@ -327,517 +318,486 @@ export class BluefinProSdk {
327
318
  this.updateTokenTimeout = null;
328
319
  }
329
320
  }
330
- login() {
331
- return __awaiter(this, void 0, void 0, function* () {
332
- var _a, _b, _c;
333
- console.log('Logging in to get the access token');
334
- if (!this.currentAccountAddress) {
335
- this.currentAccountAddress = this.bfSigner.getAddress();
336
- }
337
- console.log(`Logging in as ${this.currentAccountAddress}`);
338
- // Check if we have a valid refresh token first
339
- if (((_a = this.tokenResponse) === null || _a === void 0 ? void 0 : _a.refreshToken) && this.isRefreshTokenValid()) {
340
- try {
341
- console.log('Attempting to refresh token using refresh token');
342
- const response = yield this.authApi.authTokenRefreshPut({
343
- refreshToken: this.tokenResponse.refreshToken,
344
- });
345
- this.tokenResponse = response.data;
346
- this.tokenSetAtSeconds = Date.now() / 1000;
347
- console.log('Token refreshed successfully');
348
- return;
349
- }
350
- catch (e) {
351
- console.error('Error refreshing token:', e);
352
- // Throw the error to let the caller handle it
353
- throw new Error(`Token refresh failed: ${e instanceof Error ? e.message : 'Unknown error'}`);
354
- }
355
- }
356
- // Fallback to full login only if refresh token is not available or invalid
357
- // This should only happen during initial login or when refresh token is truly expired
321
+ async login() {
322
+ console.log('Logging in to get the access token');
323
+ if (!this.currentAccountAddress) {
324
+ this.currentAccountAddress = this.bfSigner.getAddress();
325
+ }
326
+ console.log(`Logging in as ${this.currentAccountAddress}`);
327
+ // Check if we have a valid refresh token first
328
+ if (this.tokenResponse?.refreshToken && this.isRefreshTokenValid()) {
358
329
  try {
359
- const loginRequest = {
360
- accountAddress: this.currentAccountAddress,
361
- signedAtMillis: this.getCurrentTimeMs(),
362
- audience: 'api',
363
- };
364
- const signature = yield this.bfSigner.signLoginRequest(loginRequest);
365
- const response = yield this.authApi.authV2TokenPost(signature, loginRequest, (_b = this.initializeOptions) === null || _b === void 0 ? void 0 : _b.refreshTokenValidForSeconds, (_c = this.initializeOptions) === null || _c === void 0 ? void 0 : _c.readOnly);
330
+ console.log('Attempting to refresh token using refresh token');
331
+ const response = await this.authApi.authTokenRefreshPut({
332
+ refreshToken: this.tokenResponse.refreshToken,
333
+ });
366
334
  this.tokenResponse = response.data;
367
335
  this.tokenSetAtSeconds = Date.now() / 1000;
336
+ console.log('Token refreshed successfully');
337
+ return;
368
338
  }
369
339
  catch (e) {
370
- console.error('Full login failed:', e);
371
- // If this fails and we're in a mode where logout should be disabled, don't logout
372
- if (this.disableLoginPromptOnLogout) {
373
- throw new Error(`Login failed: ${e instanceof Error ? e.message : 'Unknown error'}`);
374
- }
375
- // Otherwise, throw the error and let the caller decide
340
+ console.error('Error refreshing token:', e);
341
+ // Throw the error to let the caller handle it
342
+ throw new Error(`Token refresh failed: ${e instanceof Error ? e.message : 'Unknown error'}`);
343
+ }
344
+ }
345
+ // Fallback to full login only if refresh token is not available or invalid
346
+ // This should only happen during initial login or when refresh token is truly expired
347
+ try {
348
+ const loginRequest = {
349
+ accountAddress: this.currentAccountAddress,
350
+ signedAtMillis: this.getCurrentTimeMs(),
351
+ audience: 'api',
352
+ };
353
+ const signature = await this.bfSigner.signLoginRequest(loginRequest);
354
+ const response = await this.authApi.authV2TokenPost(signature, loginRequest, this.initializeOptions?.refreshTokenValidForSeconds, this.initializeOptions?.readOnly);
355
+ this.tokenResponse = response.data;
356
+ this.tokenSetAtSeconds = Date.now() / 1000;
357
+ }
358
+ catch (e) {
359
+ console.error('Full login failed:', e);
360
+ // If this fails and we're in a mode where logout should be disabled, don't logout
361
+ if (this.disableLoginPromptOnLogout) {
376
362
  throw new Error(`Login failed: ${e instanceof Error ? e.message : 'Unknown error'}`);
377
363
  }
378
- });
364
+ // Otherwise, throw the error and let the caller decide
365
+ throw new Error(`Login failed: ${e instanceof Error ? e.message : 'Unknown error'}`);
366
+ }
379
367
  }
380
- getAccessToken() {
381
- return __awaiter(this, void 0, void 0, function* () {
382
- if (!this.tokenResponse) {
383
- yield this.login();
384
- }
385
- if (!this.tokenResponse) {
386
- throw new Error('Unable to obtain access token');
387
- }
388
- if (this.isConnected) {
389
- if (this.isAccessTokenExpired()) {
390
- yield this.refreshToken();
391
- }
392
- }
393
- else if (this.isAccessTokenExpired()) {
394
- yield this.login();
395
- }
396
- if (!this.tokenResponse) {
397
- throw new Error('Access token unavailable after refresh');
368
+ async getAccessToken() {
369
+ if (!this.tokenResponse) {
370
+ await this.login();
371
+ }
372
+ if (!this.tokenResponse) {
373
+ throw new Error('Unable to obtain access token');
374
+ }
375
+ if (this.isConnected) {
376
+ if (this.isAccessTokenExpired()) {
377
+ await this.refreshToken();
398
378
  }
399
- return this.tokenResponse.accessToken;
400
- });
379
+ }
380
+ else if (this.isAccessTokenExpired()) {
381
+ await this.login();
382
+ }
383
+ if (!this.tokenResponse) {
384
+ throw new Error('Access token unavailable after refresh');
385
+ }
386
+ return this.tokenResponse.accessToken;
401
387
  }
402
- getOpenOrders(symbol) {
403
- return __awaiter(this, void 0, void 0, function* () {
404
- return yield this.tradeApi.getOpenOrders(symbol);
405
- });
388
+ async getOpenOrders(symbol) {
389
+ return await this.tradeApi.getOpenOrders(symbol);
406
390
  }
407
- getStandbyOrders(symbol) {
408
- return __awaiter(this, void 0, void 0, function* () {
409
- return yield this.tradeApi.getStandbyOrders(symbol);
410
- });
391
+ async getStandbyOrders(symbol) {
392
+ return await this.tradeApi.getStandbyOrders(symbol);
411
393
  }
412
- updateLeverage(symbol, leverageE9) {
413
- return __awaiter(this, void 0, void 0, function* () {
414
- if (!this.contractsConfig) {
415
- throw new Error('Missing contracts config');
416
- }
417
- const signedFields = {
418
- accountAddress: this.currentAccountAddress,
419
- idsId: this.contractsConfig.idsId,
420
- symbol: symbol,
421
- leverageE9: leverageE9,
422
- salt: this.generateSalt(),
423
- signedAtMillis: this.getCurrentTimeMs(),
424
- };
425
- const request = yield this.bfSigner.signLeverageUpdateRequest(signedFields);
426
- return yield this.tradeApi.putLeverageUpdate({
427
- signedFields,
428
- signature: request,
429
- });
394
+ async updateLeverage(symbol, leverageE9) {
395
+ if (!this.contractsConfig) {
396
+ throw new Error('Missing contracts config');
397
+ }
398
+ const signedFields = {
399
+ accountAddress: this.currentAccountAddress,
400
+ idsId: this.contractsConfig.idsId,
401
+ symbol: symbol,
402
+ leverageE9: leverageE9,
403
+ salt: this.generateSalt(),
404
+ signedAtMillis: this.getCurrentTimeMs(),
405
+ };
406
+ const request = await this.bfSigner.signLeverageUpdateRequest(signedFields);
407
+ return await this.tradeApi.putLeverageUpdate({
408
+ signedFields,
409
+ signature: request,
430
410
  });
431
411
  }
432
- createOrder(params) {
433
- return __awaiter(this, void 0, void 0, function* () {
434
- var _a, _b;
435
- if (!this.contractsConfig) {
436
- throw new Error('Missing contracts config');
437
- }
438
- const signedFields = {
439
- symbol: params.symbol,
440
- idsId: this.contractsConfig.idsId,
441
- accountAddress: this.currentAccountAddress,
442
- priceE9: params.priceE9,
443
- quantityE9: params.quantityE9,
444
- side: params.side,
445
- leverageE9: params.leverageE9,
446
- isIsolated: params.isIsolated,
447
- salt: this.generateSalt(),
448
- expiresAtMillis: params.expiresAtMillis,
449
- signedAtMillis: this.getCurrentTimeMs(),
450
- };
451
- const signature = yield this.bfSigner.signOrderRequest(signedFields);
452
- const createOrderRequest = {
453
- signedFields,
454
- signature,
455
- clientOrderId: params.clientOrderId,
456
- type: params.type,
457
- reduceOnly: (_a = params.reduceOnly) !== null && _a !== void 0 ? _a : false,
458
- postOnly: (_b = params.postOnly) !== null && _b !== void 0 ? _b : false,
459
- timeInForce: params.timeInForce,
460
- triggerPriceE9: params.triggerPriceE9,
461
- selfTradePreventionType: params.selfTradePreventionType,
462
- twapConfig: params.twapConfig,
463
- };
464
- console.log('Creating order:', createOrderRequest);
465
- return yield this.tradeApi.postCreateOrder(createOrderRequest);
466
- });
412
+ async createOrder(params) {
413
+ if (!this.contractsConfig) {
414
+ throw new Error('Missing contracts config');
415
+ }
416
+ const signedFields = {
417
+ symbol: params.symbol,
418
+ idsId: this.contractsConfig.idsId,
419
+ accountAddress: this.currentAccountAddress,
420
+ priceE9: params.priceE9,
421
+ quantityE9: params.quantityE9,
422
+ side: params.side,
423
+ leverageE9: params.leverageE9,
424
+ isIsolated: params.isIsolated,
425
+ salt: this.generateSalt(),
426
+ expiresAtMillis: params.expiresAtMillis,
427
+ signedAtMillis: this.getCurrentTimeMs(),
428
+ };
429
+ const signature = await this.bfSigner.signOrderRequest(signedFields);
430
+ const createOrderRequest = {
431
+ signedFields,
432
+ signature,
433
+ clientOrderId: params.clientOrderId,
434
+ type: params.type,
435
+ reduceOnly: params.reduceOnly ?? false,
436
+ postOnly: params.postOnly ?? false,
437
+ timeInForce: params.timeInForce,
438
+ triggerPriceE9: params.triggerPriceE9,
439
+ selfTradePreventionType: params.selfTradePreventionType,
440
+ twapConfig: params.twapConfig,
441
+ };
442
+ console.log('Creating order:', createOrderRequest);
443
+ return await this.tradeApi.postCreateOrder(createOrderRequest);
467
444
  }
468
- cancelOrder(cancelOrdersRequest) {
469
- return __awaiter(this, void 0, void 0, function* () {
470
- return yield this.tradeApi.cancelOrders(cancelOrdersRequest);
471
- });
445
+ async cancelOrder(cancelOrdersRequest) {
446
+ return await this.tradeApi.cancelOrders(cancelOrdersRequest);
472
447
  }
473
- cancelStandbyOrder(cancelOrdersRequest) {
474
- return __awaiter(this, void 0, void 0, function* () {
475
- return yield this.tradeApi.cancelStandbyOrders(cancelOrdersRequest);
476
- });
448
+ async cancelStandbyOrder(cancelOrdersRequest) {
449
+ return await this.tradeApi.cancelStandbyOrders(cancelOrdersRequest);
477
450
  }
478
- withdraw(assetSymbol, amountE9) {
479
- return __awaiter(this, void 0, void 0, function* () {
480
- const exchangeInfo = yield this.exchangeDataApi.getExchangeInfo();
481
- const asset = exchangeInfo.data.assets.find((asset) => asset.symbol === assetSymbol);
482
- if (!asset) {
483
- throw new Error(`Asset ${assetSymbol} not found`);
484
- }
485
- if (!this.contractsConfig) {
486
- throw new Error('Missing contractsConfig');
487
- }
488
- const signedFields = {
489
- assetSymbol,
490
- edsId: this.contractsConfig.edsId,
491
- accountAddress: this.currentAccountAddress,
492
- amountE9,
493
- salt: this.generateSalt(),
494
- signedAtMillis: this.getCurrentTimeMs(),
495
- };
496
- const signature = yield this.bfSigner.signWithdrawRequest(signedFields);
497
- yield this.tradeApi.postWithdraw({
498
- signedFields,
499
- signature,
500
- });
501
- console.log('Withdraw request sent:', signedFields);
451
+ async withdraw(assetSymbol, amountE9) {
452
+ const exchangeInfo = await this.exchangeDataApi.getExchangeInfo();
453
+ const asset = exchangeInfo.data.assets.find((asset) => asset.symbol === assetSymbol);
454
+ if (!asset) {
455
+ throw new Error(`Asset ${assetSymbol} not found`);
456
+ }
457
+ if (!this.contractsConfig) {
458
+ throw new Error('Missing contractsConfig');
459
+ }
460
+ const signedFields = {
461
+ assetSymbol,
462
+ edsId: this.contractsConfig.edsId,
463
+ accountAddress: this.currentAccountAddress,
464
+ amountE9,
465
+ salt: this.generateSalt(),
466
+ signedAtMillis: this.getCurrentTimeMs(),
467
+ };
468
+ const signature = await this.bfSigner.signWithdrawRequest(signedFields);
469
+ await this.tradeApi.postWithdraw({
470
+ signedFields,
471
+ signature,
502
472
  });
473
+ console.log('Withdraw request sent:', signedFields);
503
474
  }
504
- authorizeAccount(accountAddress, alias) {
505
- return __awaiter(this, void 0, void 0, function* () {
506
- if (!this.contractsConfig) {
507
- throw new Error('Missing contractsConfig');
508
- }
509
- const signedFields = {
510
- accountAddress: this.currentAccountAddress,
511
- idsId: this.contractsConfig.idsId,
512
- authorizedAccountAddress: accountAddress,
513
- salt: this.generateSalt(),
514
- signedAtMillis: this.getCurrentTimeMs(),
515
- };
516
- const signature = yield this.bfSigner.signAccountAuthorizationRequest(signedFields, true);
517
- yield this.tradeApi.putAuthorizeAccount({
518
- signedFields,
519
- signature,
520
- alias,
521
- });
522
- console.log('Authorize account request sent:', signedFields);
475
+ async authorizeAccount(accountAddress, alias) {
476
+ if (!this.contractsConfig) {
477
+ throw new Error('Missing contractsConfig');
478
+ }
479
+ const signedFields = {
480
+ accountAddress: this.currentAccountAddress,
481
+ idsId: this.contractsConfig.idsId,
482
+ authorizedAccountAddress: accountAddress,
483
+ salt: this.generateSalt(),
484
+ signedAtMillis: this.getCurrentTimeMs(),
485
+ };
486
+ const signature = await this.bfSigner.signAccountAuthorizationRequest(signedFields, true);
487
+ await this.tradeApi.putAuthorizeAccount({
488
+ signedFields,
489
+ signature,
490
+ alias,
523
491
  });
492
+ console.log('Authorize account request sent:', signedFields);
524
493
  }
525
- deauthorizeAccount(accountAddress) {
526
- return __awaiter(this, void 0, void 0, function* () {
527
- if (!this.contractsConfig) {
528
- throw new Error('Missing contractsConfig');
529
- }
530
- const signedFields = {
531
- accountAddress: this.currentAccountAddress,
532
- idsId: this.contractsConfig.idsId,
533
- authorizedAccountAddress: accountAddress,
534
- salt: this.generateSalt(),
535
- signedAtMillis: this.getCurrentTimeMs(),
536
- };
537
- const signature = yield this.bfSigner.signAccountAuthorizationRequest(signedFields, false);
538
- yield this.tradeApi.putDeauthorizeAccount({
539
- signedFields,
540
- signature,
541
- });
542
- console.log('Deauthorize account request sent:', signedFields);
494
+ async deauthorizeAccount(accountAddress) {
495
+ if (!this.contractsConfig) {
496
+ throw new Error('Missing contractsConfig');
497
+ }
498
+ const signedFields = {
499
+ accountAddress: this.currentAccountAddress,
500
+ idsId: this.contractsConfig.idsId,
501
+ authorizedAccountAddress: accountAddress,
502
+ salt: this.generateSalt(),
503
+ signedAtMillis: this.getCurrentTimeMs(),
504
+ };
505
+ const signature = await this.bfSigner.signAccountAuthorizationRequest(signedFields, false);
506
+ await this.tradeApi.putDeauthorizeAccount({
507
+ signedFields,
508
+ signature,
543
509
  });
510
+ console.log('Deauthorize account request sent:', signedFields);
544
511
  }
545
- adjustIsolatedMargin(symbol, amountE9, add) {
546
- return __awaiter(this, void 0, void 0, function* () {
547
- if (!this.contractsConfig) {
548
- throw new Error('Missing contractsConfig');
549
- }
550
- const signedFields = {
551
- symbol,
552
- idsId: this.contractsConfig.idsId,
553
- accountAddress: this.currentAccountAddress,
554
- operation: add
555
- ? AdjustMarginOperation.Add
556
- : AdjustMarginOperation.Subtract,
557
- quantityE9: amountE9,
558
- salt: this.generateSalt(),
559
- signedAtMillis: this.getCurrentTimeMs(),
560
- };
561
- const signature = yield this.bfSigner.signAdjustIsolatedMarginRequest(signedFields);
562
- yield this.tradeApi.putAdjustIsolatedMargin({
563
- signedFields,
564
- signature,
565
- });
566
- console.log('Adjust isolated margin request sent:', signedFields);
512
+ async adjustIsolatedMargin(symbol, amountE9, add) {
513
+ if (!this.contractsConfig) {
514
+ throw new Error('Missing contractsConfig');
515
+ }
516
+ const signedFields = {
517
+ symbol,
518
+ idsId: this.contractsConfig.idsId,
519
+ accountAddress: this.currentAccountAddress,
520
+ operation: add
521
+ ? AdjustMarginOperation.Add
522
+ : AdjustMarginOperation.Subtract,
523
+ quantityE9: amountE9,
524
+ salt: this.generateSalt(),
525
+ signedAtMillis: this.getCurrentTimeMs(),
526
+ };
527
+ const signature = await this.bfSigner.signAdjustIsolatedMarginRequest(signedFields);
528
+ await this.tradeApi.putAdjustIsolatedMargin({
529
+ signedFields,
530
+ signature,
567
531
  });
532
+ console.log('Adjust isolated margin request sent:', signedFields);
568
533
  }
569
- getAccountPreferences() {
570
- return __awaiter(this, void 0, void 0, function* () {
571
- return yield this.accountDataApi.getAccountPreferences();
572
- });
534
+ async getAccountPreferences() {
535
+ return await this.accountDataApi.getAccountPreferences();
573
536
  }
574
- updateAccountPreferences(updateAccountPreferenceRequest) {
575
- return __awaiter(this, void 0, void 0, function* () {
576
- return yield this.accountDataApi.putAccountPreferences(updateAccountPreferenceRequest);
577
- });
537
+ async updateAccountPreferences(updateAccountPreferenceRequest) {
538
+ return await this.accountDataApi.putAccountPreferences(updateAccountPreferenceRequest);
578
539
  }
579
540
  // Update Account Group ID.
580
541
  // If groupID is null, it will remove the account from its group.
581
542
  // An account may only belong to 1 group at a time.
582
- updateAccountGroupId(updateAccountGroupIdRequest) {
583
- return __awaiter(this, void 0, void 0, function* () {
584
- return yield this.accountDataApi.patchAccountGroupID(updateAccountGroupIdRequest);
585
- });
586
- }
587
- deposit(amountE9, accountAddress, args) {
588
- return __awaiter(this, void 0, void 0, function* () {
589
- var _a, _b, _c;
590
- const assetSymbol = 'USDC';
591
- const txb = new TransactionBlock();
592
- const assetType = (_b = (_a = this.assets) === null || _a === void 0 ? void 0 : _a.find((x) => x.symbol === assetSymbol)) === null || _b === void 0 ? void 0 : _b.assetType;
593
- if (!assetType) {
594
- throw new Error('Missing USDC asset type');
595
- }
596
- const [splitCoin, mergedCoin] = yield CoinUtils.createCoinWithBalance(this.suiClient, txb, amountE9, assetType, this.currentAccountAddress || this.bfSigner.getAddress());
597
- //build the tx
598
- (_c = this.txBuilder) === null || _c === void 0 ? void 0 : _c.depositToAssetBank(assetSymbol, accountAddress ||
599
- this.currentAccountAddress ||
600
- this.bfSigner.getAddress(), amountE9, splitCoin, {
601
- txBlock: txb,
602
- });
603
- //add the transfer objects to the tx
604
- if (mergedCoin) {
605
- txb.transferObjects([mergedCoin], this.currentAccountAddress || this.bfSigner.getAddress());
606
- }
607
- if (splitCoin) {
608
- txb.transferObjects([splitCoin], this.currentAccountAddress || this.bfSigner.getAddress());
543
+ async updateAccountGroupId(updateAccountGroupIdRequest) {
544
+ return await this.accountDataApi.patchAccountGroupID(updateAccountGroupIdRequest);
545
+ }
546
+ async deposit(amountE9, accountAddress, args) {
547
+ const assetSymbol = 'USDC';
548
+ const txb = new TransactionBlock();
549
+ const { CoinUtils } = await loadLibrarySuiRoot();
550
+ const assetType = this.assets?.find((x) => x.symbol === assetSymbol)?.assetType;
551
+ if (!assetType) {
552
+ throw new Error('Missing USDC asset type');
553
+ }
554
+ const [splitCoin, mergedCoin] = await CoinUtils.createCoinWithBalance(this.suiClient, txb, amountE9, assetType, this.currentAccountAddress || this.bfSigner.getAddress());
555
+ //build the tx
556
+ this.txBuilder?.depositToAssetBank(assetSymbol, accountAddress ||
557
+ this.currentAccountAddress ||
558
+ this.bfSigner.getAddress(), amountE9, splitCoin, {
559
+ txBlock: txb,
560
+ });
561
+ //add the transfer objects to the tx
562
+ if (mergedCoin) {
563
+ txb.transferObjects([mergedCoin], this.currentAccountAddress || this.bfSigner.getAddress());
564
+ }
565
+ if (splitCoin) {
566
+ txb.transferObjects([splitCoin], this.currentAccountAddress || this.bfSigner.getAddress());
567
+ }
568
+ if (args && args.sponsored) {
569
+ // build the gasless tx payload bytes
570
+ const gaslessTxPayloadBytes = await this.buildGaslessTxPayloadBytes(txb);
571
+ try {
572
+ const request = {
573
+ txBytes: gaslessTxPayloadBytes,
574
+ };
575
+ // sponsor gas for the transaction
576
+ const sponsorTxApiResponse = await this.accountDataApi.sponsorTx(request);
577
+ const txBlockFromBytes = TransactionBlock.from(sponsorTxApiResponse.data.txBytes);
578
+ // sign the transaction with user's wallet
579
+ const userSignedTx = await this.bfSigner.signTx(txBlockFromBytes, this.suiClient);
580
+ // execute the transaction with both user's signature and sponsor's signature
581
+ const response = await this.bfSigner.executeSponsoredTx(userSignedTx.bytes, userSignedTx.signature, sponsorTxApiResponse.data.signature, this.suiClient);
582
+ return response;
609
583
  }
610
- if (args && args.sponsored) {
611
- // build the gasless tx payload bytes
612
- const gaslessTxPayloadBytes = yield this.buildGaslessTxPayloadBytes(txb);
613
- try {
614
- const request = {
615
- txBytes: gaslessTxPayloadBytes,
616
- };
617
- // sponsor gas for the transaction
618
- const sponsorTxApiResponse = yield this.accountDataApi.sponsorTx(request);
619
- const txBlockFromBytes = TransactionBlock.from(sponsorTxApiResponse.data.txBytes);
620
- // sign the transaction with user's wallet
621
- const userSignedTx = yield this.bfSigner.signTx(txBlockFromBytes, this.suiClient);
622
- // execute the transaction with both user's signature and sponsor's signature
623
- const response = yield this.bfSigner.executeSponsoredTx(userSignedTx.bytes, userSignedTx.signature, sponsorTxApiResponse.data.signature, this.suiClient);
624
- return response;
625
- }
626
- catch (error) {
627
- if (args === null || args === void 0 ? void 0 : args.fallbackToExecuteTx) {
628
- return this.bfSigner.executeTx(txb, this.suiClient);
629
- }
630
- throw error;
584
+ catch (error) {
585
+ if (args?.fallbackToExecuteTx) {
586
+ return this.bfSigner.executeTx(txb, this.suiClient);
631
587
  }
588
+ throw error;
632
589
  }
633
- else {
634
- return this.bfSigner.executeTx(txb, this.suiClient);
635
- }
636
- });
590
+ }
591
+ else {
592
+ return this.bfSigner.executeTx(txb, this.suiClient);
593
+ }
637
594
  }
638
595
  /**
639
596
  * Batch claim rewards on-chain using RewardsDistributorInteractor
640
597
  * @param payload Array of claim payloads with signatures
641
598
  * @returns Transaction response
642
599
  */
643
- batchClaimRewards(payload) {
644
- return __awaiter(this, void 0, void 0, function* () {
645
- // Get the rewards contract config from API (same as useClaimConfigQuery)
646
- const { data } = yield this.rewardsDataApi.getContractConfig();
647
- if (!data) {
648
- throw new Error('Failed to get rewards contract config');
600
+ async batchClaimRewards(payload) {
601
+ // Get the rewards contract config from API (same as useClaimConfigQuery)
602
+ const { data } = await this.rewardsDataApi.getContractConfig();
603
+ if (!data) {
604
+ throw new Error('Failed to get rewards contract config');
605
+ }
606
+ // Get the signer from BluefinRequestSigner
607
+ const signer = this.bfSigner.wallet;
608
+ // Create the RewardsDistributorInteractor
609
+ const { RewardsDistributorInteractor } = await loadRewardsDistributorInteractor();
610
+ const interactor = new RewardsDistributorInteractor(this.suiClient, data, signer, this.bfSigner.isUIWallet());
611
+ // Transform payload to the format expected by claimRewardsBatch
612
+ const batch = payload.map(({ signature, sigPayload }) => ({
613
+ signature,
614
+ payload: sigPayload,
615
+ }));
616
+ // Execute the batch claim
617
+ const tx = await interactor.claimRewardsBatch(batch);
618
+ return tx;
619
+ }
620
+ async refreshToken(force = false) {
621
+ if (!this.isConnected)
622
+ return;
623
+ // If already refreshing, wait for that operation to complete
624
+ if (this.isRefreshing) {
625
+ if (this.refreshTokenPromise) {
626
+ await this.refreshTokenPromise;
649
627
  }
650
- // Get the signer from BluefinRequestSigner
651
- const signer = this.bfSigner.wallet;
652
- // Create the RewardsDistributorInteractor
653
- const interactor = new RewardsDistributorInteractor(this.suiClient, data, signer, this.bfSigner.isUIWallet());
654
- // Transform payload to the format expected by claimRewardsBatch
655
- const batch = payload.map(({ signature, sigPayload }) => ({
656
- signature,
657
- payload: sigPayload,
658
- }));
659
- // Execute the batch claim
660
- const tx = yield interactor.claimRewardsBatch(batch);
661
- return tx;
662
- });
628
+ return;
629
+ }
630
+ // Check if token needs refreshing
631
+ if (!this.isAccessTokenExpired() && !force) {
632
+ return;
633
+ }
634
+ this.isRefreshing = true;
635
+ try {
636
+ this.refreshTokenPromise = this.performTokenRefresh();
637
+ await this.refreshTokenPromise;
638
+ }
639
+ finally {
640
+ this.isRefreshing = false;
641
+ this.refreshTokenPromise = null;
642
+ }
663
643
  }
664
- refreshToken() {
665
- return __awaiter(this, arguments, void 0, function* (force = false) {
666
- if (!this.isConnected)
667
- return;
668
- // If already refreshing, wait for that operation to complete
669
- if (this.isRefreshing) {
670
- if (this.refreshTokenPromise) {
671
- yield this.refreshTokenPromise;
644
+ async performTokenRefresh() {
645
+ const maxRetries = 5;
646
+ let retryCount = 0;
647
+ let consecutiveNetworkErrors = 0;
648
+ while (retryCount < maxRetries) {
649
+ try {
650
+ console.log(`Refreshing token (attempt ${retryCount + 1}/${maxRetries})`);
651
+ // Check if refresh token is still valid
652
+ if (!this.isRefreshTokenValid()) {
653
+ console.log('Refresh token is expired or invalid, triggering logout');
654
+ this.logout();
655
+ return;
672
656
  }
657
+ await this.loginAndUpdateToken();
658
+ console.log('Token refreshed successfully');
659
+ consecutiveNetworkErrors = 0; // Reset network error counter on success
673
660
  return;
674
661
  }
675
- // Check if token needs refreshing
676
- if (!this.isAccessTokenExpired() && !force) {
677
- return;
678
- }
679
- this.isRefreshing = true;
680
- try {
681
- this.refreshTokenPromise = this.performTokenRefresh();
682
- yield this.refreshTokenPromise;
683
- }
684
- finally {
685
- this.isRefreshing = false;
686
- this.refreshTokenPromise = null;
687
- }
688
- });
689
- }
690
- performTokenRefresh() {
691
- return __awaiter(this, void 0, void 0, function* () {
692
- const maxRetries = 5;
693
- let retryCount = 0;
694
- let consecutiveNetworkErrors = 0;
695
- while (retryCount < maxRetries) {
696
- try {
697
- console.log(`Refreshing token (attempt ${retryCount + 1}/${maxRetries})`);
698
- // Check if refresh token is still valid
699
- if (!this.isRefreshTokenValid()) {
700
- console.log('Refresh token is expired or invalid, triggering logout');
701
- this.logout();
702
- return;
662
+ catch (error) {
663
+ retryCount++;
664
+ console.error(`Error refreshing token (attempt ${retryCount}):`, error);
665
+ // Check if this is a network error that we should retry
666
+ const isNetworkError = error instanceof Error &&
667
+ (error.message.includes('Network Error') ||
668
+ error.message.includes('ERR_NETWORK') ||
669
+ error.message.includes('ECONNREFUSED') ||
670
+ error.message.includes('timeout') ||
671
+ error.message.includes('ERR_NETWORK_IO_SUSPENDED'));
672
+ // Check if we're currently offline (browser environment only)
673
+ const isOffline = typeof navigator !== 'undefined' &&
674
+ 'onLine' in navigator &&
675
+ !navigator.onLine;
676
+ if (isNetworkError) {
677
+ consecutiveNetworkErrors++;
678
+ }
679
+ // If we're offline, don't count this as a "real" error - just wait for network to come back
680
+ if (isOffline) {
681
+ console.log('User is offline, will retry when network comes back online');
682
+ return;
683
+ }
684
+ // If it's not a network error and login failed (tokenResponse is null), logout immediately
685
+ if (!isNetworkError && !this.tokenResponse) {
686
+ console.error('Login failed permanently, triggering logout');
687
+ this.logout();
688
+ return;
689
+ }
690
+ // If we've had too many consecutive network errors, pause refresh attempts temporarily
691
+ if (consecutiveNetworkErrors >= 10) {
692
+ // Clear any scheduled refresh
693
+ if (this.updateTokenTimeout) {
694
+ clearTimeout(this.updateTokenTimeout);
695
+ this.updateTokenTimeout = null;
703
696
  }
704
- yield this.loginAndUpdateToken();
705
- console.log('Token refreshed successfully');
706
- consecutiveNetworkErrors = 0; // Reset network error counter on success
697
+ setTimeout(() => {
698
+ console.log('Resuming token refresh attempts');
699
+ this.scheduleTokenRefresh(); // Reschedule refresh when resuming
700
+ }, 300000); // 5 minutes
707
701
  return;
708
702
  }
709
- catch (error) {
710
- retryCount++;
711
- console.error(`Error refreshing token (attempt ${retryCount}):`, error);
712
- // Check if this is a network error that we should retry
713
- const isNetworkError = error instanceof Error &&
714
- (error.message.includes('Network Error') ||
715
- error.message.includes('ERR_NETWORK') ||
716
- error.message.includes('ECONNREFUSED') ||
717
- error.message.includes('timeout') ||
718
- error.message.includes('ERR_NETWORK_IO_SUSPENDED'));
719
- // Check if we're currently offline (browser environment only)
720
- const isOffline = typeof navigator !== 'undefined' &&
721
- 'onLine' in navigator &&
722
- !navigator.onLine;
703
+ if (retryCount >= maxRetries && !isOffline) {
723
704
  if (isNetworkError) {
724
- consecutiveNetworkErrors++;
725
- }
726
- // If we're offline, don't count this as a "real" error - just wait for network to come back
727
- if (isOffline) {
728
- console.log('User is offline, will retry when network comes back online');
729
- return;
705
+ console.warn('Max retries reached due to network errors, will retry later');
706
+ return; // Don't logout for network issues, just wait for next interval
730
707
  }
731
- // If it's not a network error and login failed (tokenResponse is null), logout immediately
732
- if (!isNetworkError && !this.tokenResponse) {
733
- console.error('Login failed permanently, triggering logout');
708
+ else {
709
+ console.error('Max retries reached, triggering logout');
734
710
  this.logout();
735
711
  return;
736
712
  }
737
- // If we've had too many consecutive network errors, pause refresh attempts temporarily
738
- if (consecutiveNetworkErrors >= 10) {
739
- // Clear any scheduled refresh
740
- if (this.updateTokenTimeout) {
741
- clearTimeout(this.updateTokenTimeout);
742
- this.updateTokenTimeout = null;
743
- }
744
- setTimeout(() => {
745
- console.log('Resuming token refresh attempts');
746
- this.scheduleTokenRefresh(); // Reschedule refresh when resuming
747
- }, 300000); // 5 minutes
748
- return;
749
- }
750
- if (retryCount >= maxRetries && !isOffline) {
751
- if (isNetworkError) {
752
- console.warn('Max retries reached due to network errors, will retry later');
753
- return; // Don't logout for network issues, just wait for next interval
754
- }
755
- else {
756
- console.error('Max retries reached, triggering logout');
757
- this.logout();
758
- return;
759
- }
760
- }
761
- // Exponential backoff: wait 2^retryCount seconds, but cap at 30 seconds for network errors
762
- const baseDelay = isNetworkError ? 5000 : 2000; // Start with 5s for network errors, 2s for others
763
- const delayMs = Math.min(baseDelay * Math.pow(2, retryCount - 1), 30000);
764
- console.log(`Retrying in ${delayMs}ms...`);
765
- yield new Promise((resolve) => setTimeout(resolve, delayMs));
766
713
  }
714
+ // Exponential backoff: wait 2^retryCount seconds, but cap at 30 seconds for network errors
715
+ const baseDelay = isNetworkError ? 5000 : 2000; // Start with 5s for network errors, 2s for others
716
+ const delayMs = Math.min(baseDelay * Math.pow(2, retryCount - 1), 30000);
717
+ console.log(`Retrying in ${delayMs}ms...`);
718
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
767
719
  }
768
- });
720
+ }
769
721
  }
770
- createAccountDataStreamListener(handler) {
771
- return __awaiter(this, void 0, void 0, function* () {
772
- const accessToken = yield this.getAccessToken();
773
- return new Promise((resolve) => {
774
- const ws = new WebSocket(this.configs[Services.AccountWebsocket].basePath, {
775
- headers: {
776
- Authorization: `Bearer ${accessToken}`,
777
- },
778
- });
779
- ws.onmessage = (event) => __awaiter(this, void 0, void 0, function* () {
780
- yield handler(JSON.parse(event.data));
781
- });
782
- ws.on('open', () => {
783
- resolve(ws);
784
- });
722
+ async createAccountDataStreamListener(handler) {
723
+ const accessToken = await this.getAccessToken();
724
+ return new Promise((resolve) => {
725
+ const ws = new WebSocket(this.configs[Services.AccountWebsocket].basePath, {
726
+ headers: {
727
+ Authorization: `Bearer ${accessToken}`,
728
+ },
729
+ });
730
+ ws.onmessage = async (event) => {
731
+ await handler(JSON.parse(event.data));
732
+ };
733
+ ws.on('open', () => {
734
+ resolve(ws);
785
735
  });
786
736
  });
787
737
  }
788
- createMarketDataStreamListener(handler) {
789
- return __awaiter(this, void 0, void 0, function* () {
790
- return new Promise((resolve) => {
791
- const ws = new WebSocket(this.configs[Services.MarketWebsocket].basePath);
792
- ws.onmessage = (event) => __awaiter(this, void 0, void 0, function* () {
793
- yield handler(JSON.parse(event.data));
794
- });
795
- ws.on('open', () => {
796
- resolve(ws);
797
- });
738
+ async createMarketDataStreamListener(handler) {
739
+ return new Promise((resolve) => {
740
+ const ws = new WebSocket(this.configs[Services.MarketWebsocket].basePath);
741
+ ws.onmessage = async (event) => {
742
+ await handler(JSON.parse(event.data));
743
+ };
744
+ ws.on('open', () => {
745
+ resolve(ws);
798
746
  });
799
747
  });
800
748
  }
801
- logout() {
802
- return __awaiter(this, void 0, void 0, function* () {
803
- var _a;
804
- console.log('Logging out');
805
- if (this.updateTokenTimeout) {
806
- clearTimeout(this.updateTokenTimeout);
807
- this.updateTokenTimeout = null;
808
- }
809
- this.tokenResponse = null;
810
- this.tokenSetAtSeconds = null;
811
- this.isConnected = false;
812
- (_a = this.onLogout) === null || _a === void 0 ? void 0 : _a.call(this);
813
- });
749
+ async logout() {
750
+ console.log('Logging out');
751
+ if (this.updateTokenTimeout) {
752
+ clearTimeout(this.updateTokenTimeout);
753
+ this.updateTokenTimeout = null;
754
+ }
755
+ this.tokenResponse = null;
756
+ this.tokenSetAtSeconds = null;
757
+ this.isConnected = false;
758
+ this.onLogout?.();
814
759
  }
815
- dispose() {
816
- return __awaiter(this, void 0, void 0, function* () {
817
- console.log('Disposing SDK resources');
818
- if (this.updateTokenTimeout) {
819
- clearTimeout(this.updateTokenTimeout);
820
- this.updateTokenTimeout = null;
821
- }
822
- // Clean up visibility change listener
823
- if (this.visibilityChangeHandler && typeof document !== 'undefined') {
824
- document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
825
- this.visibilityChangeHandler = undefined;
760
+ async dispose() {
761
+ console.log('Disposing SDK resources');
762
+ if (this.updateTokenTimeout) {
763
+ clearTimeout(this.updateTokenTimeout);
764
+ this.updateTokenTimeout = null;
765
+ }
766
+ // Clean up visibility change listener
767
+ if (this.visibilityChangeHandler && typeof document !== 'undefined') {
768
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
769
+ this.visibilityChangeHandler = undefined;
770
+ }
771
+ // Clean up network change listeners
772
+ if (typeof window !== 'undefined') {
773
+ if (this.onlineHandler) {
774
+ window.removeEventListener('online', this.onlineHandler);
775
+ this.onlineHandler = undefined;
826
776
  }
827
- // Clean up network change listeners
828
- if (typeof window !== 'undefined') {
829
- if (this.onlineHandler) {
830
- window.removeEventListener('online', this.onlineHandler);
831
- this.onlineHandler = undefined;
832
- }
833
- if (this.offlineHandler) {
834
- window.removeEventListener('offline', this.offlineHandler);
835
- this.offlineHandler = undefined;
836
- }
777
+ if (this.offlineHandler) {
778
+ window.removeEventListener('offline', this.offlineHandler);
779
+ this.offlineHandler = undefined;
837
780
  }
838
- this.isConnected = false;
839
- });
781
+ }
782
+ this.isConnected = false;
840
783
  }
784
+ /**
785
+ * @description
786
+ * build gasless transaction payload bytes
787
+ * @param tx transcation block
788
+ * @returns string
789
+ * */
790
+ buildGaslessTxPayloadBytes = async (txb) => {
791
+ try {
792
+ const { SuiBlocks } = await loadLibrarySuiRoot();
793
+ return await SuiBlocks.buildGaslessTxPayloadBytes(txb, this.suiClient);
794
+ }
795
+ catch (error) {
796
+ throw new Error(error instanceof Error
797
+ ? error.message
798
+ : 'Build gasless tx payload bytes failed');
799
+ }
800
+ };
841
801
  /**
842
802
  * @description
843
803
  * Get the transaction builder instance
@@ -855,5 +815,4 @@ export class BluefinProSdk {
855
815
  return this.bfSigner;
856
816
  }
857
817
  }
858
- BluefinProSdk.TOKEN_REFRESH_THRESHOLD_PERCENTAGE = 0.8;
859
818
  //# sourceMappingURL=sdk.js.map