pinpet-sdk 2.0.1 → 2.0.3

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.
@@ -22,8 +22,6 @@ export interface PinPetSdkOptions {
22
22
  fee_recipient?: string;
23
23
  base_fee_recipient?: string;
24
24
  params_account?: string;
25
- debug_log_path?: string;
26
- debugLogPath?: string;
27
25
  }
28
26
 
29
27
  // ========================= 订单和交易相关类型 =========================
@@ -258,8 +256,7 @@ export declare class PinPetSdk {
258
256
  baseFeeRecipient: PublicKey;
259
257
  paramsAccount: PublicKey;
260
258
  spinFastApiUrl: string;
261
- debugLogPath: string | null;
262
-
259
+
263
260
  // 常量
264
261
  readonly MAX_ORDERS_COUNT: number;
265
262
  readonly FIND_MAX_ORDERS_COUNT: number;
package/dist/index.d.ts CHANGED
@@ -22,7 +22,6 @@ export interface PinPetSdkOptions {
22
22
  feeRecipient?: string;
23
23
  baseFeeRecipient?: string;
24
24
  paramsAccount?: string;
25
- debugLogPath?: string;
26
25
  }
27
26
 
28
27
  // ========================= 订单和交易相关类型 =========================
@@ -257,8 +256,7 @@ export declare class PinPetSdk {
257
256
  baseFeeRecipient: PublicKey;
258
257
  paramsAccount: PublicKey;
259
258
  pinPetFastApiUrl: string;
260
- debugLogPath: string | null;
261
-
259
+
262
260
  // 常量
263
261
  readonly MAX_ORDERS_COUNT: number;
264
262
  readonly FIND_MAX_ORDERS_COUNT: number;
@@ -15632,17 +15632,7 @@ const { Buffer: Buffer$5 } = require$$3__default["default"];
15632
15632
  const { MAX_CANDIDATE_INDICES: MAX_CANDIDATE_INDICES$2 } = utils$2;
15633
15633
 
15634
15634
  // 环境检测和条件加载
15635
- const IS_NODE$1 = typeof process !== 'undefined' && process.versions && process.versions.node;
15636
-
15637
- let fs$2, path$2;
15638
- if (IS_NODE$1) {
15639
- try {
15640
- fs$2 = require('fs');
15641
- path$2 = require('path');
15642
- } catch (e) {
15643
- console.warn('File system modules not available in trading module');
15644
- }
15645
- }
15635
+ typeof process !== 'undefined' && process.versions && process.versions.node;
15646
15636
 
15647
15637
  /**
15648
15638
  * Trading Module
@@ -16442,30 +16432,6 @@ class TradingModule$1 {
16442
16432
  };
16443
16433
  }
16444
16434
 
16445
-
16446
-
16447
- // ========== Debug File Management Methods ==========
16448
-
16449
- /**
16450
- * 安全地写入调试日志
16451
- * Safely write debug log
16452
- * @private
16453
- * @param {string} fileName - 文件名
16454
- * @param {string} content - 内容
16455
- */
16456
- _writeDebugLog(fileName, content) {
16457
- if (!IS_NODE$1 || !this.sdk.debugLogPath || typeof this.sdk.debugLogPath !== 'string' || !fs$2 || !path$2) {
16458
- return; // 浏览器环境或文件系统不可用时直接返回
16459
- }
16460
-
16461
- try {
16462
- const fullPath = path$2.join(this.sdk.debugLogPath, fileName);
16463
- fs$2.appendFileSync(fullPath, content);
16464
- } catch (error) {
16465
- console.warn(`Warning: Failed to write debug log to ${fileName}:`, error.message);
16466
- }
16467
- }
16468
-
16469
16435
  // ========== PDA Calculation Methods ==========
16470
16436
 
16471
16437
  /**
@@ -29526,11 +29492,11 @@ var populate$1 = function (dst, src) {
29526
29492
 
29527
29493
  var CombinedStream = combined_stream;
29528
29494
  var util$1 = require$$1__default$1["default"];
29529
- var path$1 = require$$1__default["default"];
29495
+ var path = require$$1__default["default"];
29530
29496
  var http$2 = require$$3__default$1["default"];
29531
29497
  var https$2 = require$$4__default["default"];
29532
29498
  var parseUrl$2 = require$$0__default$5["default"].parse;
29533
- var fs$1 = require$$0__default$1["default"];
29499
+ var fs = require$$0__default$1["default"];
29534
29500
  var Stream = require$$0__default$4["default"].Stream;
29535
29501
  var crypto$2 = require$$8__default["default"];
29536
29502
  var mime = mimeTypes;
@@ -29657,7 +29623,7 @@ FormData$2.prototype._lengthRetriever = function (value, callback) {
29657
29623
  // not that fast snoopy
29658
29624
  } else {
29659
29625
  // still need to fetch file size from fs
29660
- fs$1.stat(value.path, function (err, stat) {
29626
+ fs.stat(value.path, function (err, stat) {
29661
29627
  if (err) {
29662
29628
  callback(err);
29663
29629
  return;
@@ -29744,17 +29710,17 @@ FormData$2.prototype._getContentDisposition = function (value, options) { // esl
29744
29710
 
29745
29711
  if (typeof options.filepath === 'string') {
29746
29712
  // custom filepath for relative paths
29747
- filename = path$1.normalize(options.filepath).replace(/\\/g, '/');
29713
+ filename = path.normalize(options.filepath).replace(/\\/g, '/');
29748
29714
  } else if (options.filename || (value && (value.name || value.path))) {
29749
29715
  /*
29750
29716
  * custom filename take precedence
29751
29717
  * formidable and the browser add a name property
29752
29718
  * fs- and request- streams have path property
29753
29719
  */
29754
- filename = path$1.basename(options.filename || (value && (value.name || value.path)));
29720
+ filename = path.basename(options.filename || (value && (value.name || value.path)));
29755
29721
  } else if (value && value.readable && hasOwn(value, 'httpVersion')) {
29756
29722
  // or try http response
29757
- filename = path$1.basename(value.client._httpMessage.path || '');
29723
+ filename = path.basename(value.client._httpMessage.path || '');
29758
29724
  }
29759
29725
 
29760
29726
  if (filename) {
@@ -48811,6 +48777,154 @@ class ToolsModule$1 {
48811
48777
  }
48812
48778
  };
48813
48779
  }
48780
+
48781
+ /**
48782
+ * Validate cooldown PDA approval_token_amount matches user's current token balance
48783
+ *
48784
+ * Use Cases:
48785
+ * - Before trading, verify if the cooldown PDA is in sync with user's token balance
48786
+ * - Check if user needs to call approveTrade after receiving tokens
48787
+ * - Validate cooldown state for security checks
48788
+ *
48789
+ * @param {Object} params - Parameters
48790
+ * @param {PublicKey|string} params.mint - Token mint address
48791
+ * @param {Keypair|Object} params.wallet - User wallet (can be Keypair or object with publicKey)
48792
+ * @param {anchor.BN|number|string} [params.tokenBalance] - Optional: user's current token balance, if not provided will fetch from chain
48793
+ * @returns {Promise<Object>} Validation result with detailed info
48794
+ *
48795
+ * @example
48796
+ * // Auto-fetch token balance from chain
48797
+ * const result = await sdk.tools.validateCooldown({
48798
+ * mint: 'xxxxx',
48799
+ * wallet: userKeypair
48800
+ * });
48801
+ *
48802
+ * // Provide token balance manually
48803
+ * const result = await sdk.tools.validateCooldown({
48804
+ * mint: 'xxxxx',
48805
+ * wallet: userKeypair,
48806
+ * tokenBalance: new anchor.BN('1000000')
48807
+ * });
48808
+ *
48809
+ * console.log(result.isValid); // true/false
48810
+ * console.log(result.cooldownInfo.approvalTokenAmount);
48811
+ * console.log(result.tokenBalance);
48812
+ */
48813
+ async validateCooldown(params) {
48814
+ const { mint, wallet, tokenBalance } = params;
48815
+
48816
+ // Validate parameters
48817
+ if (!mint) {
48818
+ throw new Error('mint parameter is required');
48819
+ }
48820
+ if (!wallet) {
48821
+ throw new Error('wallet parameter is required');
48822
+ }
48823
+
48824
+ // Convert mint to PublicKey
48825
+ const mintPubkey = typeof mint === 'string' ? new PublicKey$2(mint) : mint;
48826
+ const walletPubkey = wallet.publicKey || wallet;
48827
+
48828
+ // Calculate user token account
48829
+ const userTokenAccount = await getAssociatedTokenAddress(
48830
+ mintPubkey,
48831
+ walletPubkey
48832
+ );
48833
+
48834
+ // Calculate trade cooldown PDA
48835
+ const [cooldown] = PublicKey$2.findProgramAddressSync(
48836
+ [
48837
+ Buffer.from('trade_cooldown'),
48838
+ mintPubkey.toBuffer(),
48839
+ walletPubkey.toBuffer()
48840
+ ],
48841
+ this.sdk.programId
48842
+ );
48843
+
48844
+ // Get cooldown account data
48845
+ const cooldownAccountInfo = await this.sdk.connection.getAccountInfo(cooldown);
48846
+ if (!cooldownAccountInfo) {
48847
+ // Cooldown PDA does not exist, return status without throwing error
48848
+ return {
48849
+ isValid: false,
48850
+ exists: false,
48851
+ reason: 'COOLDOWN_NOT_EXISTS',
48852
+ message: 'Cooldown PDA does not exist. User has never traded this token or needs to call approveTrade first.',
48853
+ cooldownInfo: null,
48854
+ tokenBalance: null,
48855
+ accounts: {
48856
+ mintAccount: mintPubkey,
48857
+ userTokenAccount: userTokenAccount,
48858
+ cooldown: cooldown,
48859
+ wallet: walletPubkey,
48860
+ }
48861
+ };
48862
+ }
48863
+
48864
+ const accountsCoder = new anchor$1.BorshAccountsCoder(this.sdk.program.idl);
48865
+ let cooldownAccountData;
48866
+ try {
48867
+ cooldownAccountData = accountsCoder.decode('TradeCooldown', cooldownAccountInfo.data);
48868
+ } catch (e1) {
48869
+ try {
48870
+ cooldownAccountData = accountsCoder.decode('tradeCooldown', cooldownAccountInfo.data);
48871
+ } catch (e2) {
48872
+ throw new Error(`Cannot decode cooldown account: ${e1.message}`);
48873
+ }
48874
+ }
48875
+
48876
+ // Get user's current token balance
48877
+ let currentTokenBalance;
48878
+ if (tokenBalance !== undefined && tokenBalance !== null) {
48879
+ // Use provided token balance
48880
+ if (anchor$1.BN.isBN(tokenBalance)) {
48881
+ currentTokenBalance = tokenBalance;
48882
+ } else {
48883
+ currentTokenBalance = new anchor$1.BN(tokenBalance.toString());
48884
+ }
48885
+ } else {
48886
+ // Fetch token balance from chain
48887
+ const userTokenAccountInfo = await this.sdk.connection.getAccountInfo(userTokenAccount);
48888
+ if (!userTokenAccountInfo) {
48889
+ throw new Error(`User token account does not exist for mint: ${mint} and wallet: ${walletPubkey.toString()}`);
48890
+ }
48891
+
48892
+ try {
48893
+ // Fetch SPL token account balance
48894
+ const tokenAccountInfo = await this.sdk.connection.getTokenAccountBalance(userTokenAccount);
48895
+ currentTokenBalance = new anchor$1.BN(tokenAccountInfo.value.amount);
48896
+ } catch (e) {
48897
+ throw new Error(`Cannot fetch token balance: ${e.message}`);
48898
+ }
48899
+ }
48900
+
48901
+ // Compare approval_token_amount with current token balance
48902
+ // Valid if approval_token_amount >= current token balance
48903
+ const approvalTokenAmount = new anchor$1.BN(cooldownAccountData.approvalTokenAmount.toString());
48904
+ const isValid = approvalTokenAmount.gte(currentTokenBalance);
48905
+
48906
+ // Return result
48907
+ return {
48908
+ isValid,
48909
+ exists: true,
48910
+ reason: isValid ? 'VALID' : 'AMOUNT_MISMATCH',
48911
+ message: isValid
48912
+ ? 'Cooldown validation passed. approval_token_amount >= token_balance'
48913
+ : 'Cooldown validation failed. approval_token_amount < token_balance. User needs to call approveTrade.',
48914
+ cooldownInfo: {
48915
+ approvalTokenAmount: cooldownAccountData.approvalTokenAmount,
48916
+ lastTradeTime: cooldownAccountData.lastTradeTime,
48917
+ bump: cooldownAccountData.bump,
48918
+ },
48919
+ tokenBalance: currentTokenBalance,
48920
+ accounts: {
48921
+ mintAccount: mintPubkey,
48922
+ userTokenAccount: userTokenAccount,
48923
+ cooldown: cooldown,
48924
+ wallet: walletPubkey,
48925
+ }
48926
+ };
48927
+ }
48814
48928
  }
48815
48929
 
48816
48930
  var tools = ToolsModule$1;
@@ -52876,22 +52990,13 @@ const { PublicKey: PublicKey$1 } = require$$0__default["default"];
52876
52990
  const { Buffer: Buffer$1 } = require$$3__default["default"];
52877
52991
 
52878
52992
  // 环境检测和条件加载
52879
- const IS_NODE = typeof process !== 'undefined' && process.versions && process.versions.node;
52993
+ typeof process !== 'undefined' && process.versions && process.versions.node;
52880
52994
 
52881
52995
  // 确保全局可用(兼容现有代码)
52882
52996
  if (typeof commonjsGlobal !== 'undefined' && !commonjsGlobal.Buffer) {
52883
52997
  commonjsGlobal.Buffer = Buffer$1;
52884
52998
  }
52885
52999
 
52886
- let fs, path;
52887
- if (IS_NODE) {
52888
- try {
52889
- fs = require('fs');
52890
- path = require('path');
52891
- } catch (e) {
52892
- console.warn('File system modules not available');
52893
- }
52894
- }
52895
53000
  const TradingModule = trading;
52896
53001
  const TokenModule = token;
52897
53002
  const ParamModule = param;
@@ -52949,13 +53054,6 @@ class PinPetSdk$1 {
52949
53054
  // 在流动性不足时, 建议实际使用流动性的比例, 分每 (1000=100%)
52950
53055
  this.SUGGEST_LIQ_RATIO = 975; // 97.5% (1000=100%)
52951
53056
 
52952
- // 只在 Node.js 环境中启用调试日志
52953
- this.debugLogPath = IS_NODE && fs ? (this.options.debugLogPath || null) : null;
52954
-
52955
- // 初始化调试文件
52956
- this._initDebugFiles();
52957
-
52958
-
52959
53057
  // Initialize Anchor program
52960
53058
  this.program = this._initProgram(this.options);
52961
53059
 
@@ -53053,52 +53151,6 @@ class PinPetSdk$1 {
53053
53151
  return new anchor.Program(spinpetIdl$1, this.programId);
53054
53152
  }
53055
53153
 
53056
-
53057
- // ========== Debug File Management Methods ==========
53058
-
53059
- /**
53060
- * 初始化调试文件,删除旧文件
53061
- * Initialize debug files, delete old files
53062
- * @private
53063
- */
53064
- _initDebugFiles() {
53065
- if (!this.debugLogPath || !IS_NODE || !fs || !path) {
53066
- return; // 浏览器环境或文件系统不可用
53067
- }
53068
-
53069
- try {
53070
- const files = ['orderPda.txt', 'orderOpen.txt'];
53071
- files.forEach(file => {
53072
- const filePath = path.join(this.debugLogPath, file);
53073
- if (fs.existsSync(filePath)) {
53074
- fs.unlinkSync(filePath);
53075
- }
53076
- });
53077
- } catch (error) {
53078
- console.warn('Warning: Failed to initialize debug files:', error.message);
53079
- }
53080
- }
53081
-
53082
- /**
53083
- * 安全地写入调试日志
53084
- * Safely write debug log
53085
- * @private
53086
- * @param {string} fileName - 文件名
53087
- * @param {string} content - 内容
53088
- */
53089
- _writeDebugLog(fileName, content) {
53090
- if (!this.debugLogPath || !IS_NODE || !fs || !path) {
53091
- return; // 静默失败,不报错
53092
- }
53093
-
53094
- try {
53095
- const filePath = path.join(this.debugLogPath, fileName);
53096
- fs.appendFileSync(filePath, content);
53097
- } catch (error) {
53098
- console.warn(`Warning: Failed to write debug log to ${fileName}:`, error.message);
53099
- }
53100
- }
53101
-
53102
53154
  // ========== Unified Data Interface Routing Method ==========
53103
53155
 
53104
53156
  /**