@cryptorubic/web3 0.8.17-alpha.solana.13 → 0.8.17-alpha.solana.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cryptorubic/web3",
3
- "version": "0.8.17-alpha.solana.13",
3
+ "version": "0.8.17-alpha.solana.15",
4
4
  "dependencies": {
5
5
  "@ethersproject/bignumber": "^5.8.0",
6
6
  "@mysten/sui": "^1.24.0",
@@ -19,6 +19,8 @@ export declare class SolanaAdapter extends AbstractAdapter<Connection, Connectio
19
19
  multicallByContract<T>(_contracts: MulticallParameters, _allowErrors?: boolean): Promise<MulticallResponse<T>[]>;
20
20
  multicallByAddress<T>(_address: string, _abi: Abi, _method: string, _methodArgs?: unknown[][], _allowErrors?: boolean): Promise<MulticallResponse<T>[]>;
21
21
  simulateTransaction(config: SolanaTxConfig, timeout?: number): Promise<string>;
22
+ private updatePriorityFee;
23
+ private encodeNumberToArrayLE;
22
24
  checkEnoughBalance(token: TokenAmount | PriceTokenAmount, walletAddress: string): Promise<boolean>;
23
25
  getBalance(userAddress: string, tokenAddress: string): Promise<BigNumber>;
24
26
  /**
@@ -49,12 +49,21 @@ class SolanaAdapter extends abstract_adapter_1.AbstractAdapter {
49
49
  const { blockhash } = await this.public.getLatestBlockhash();
50
50
  const tx = web3_js_1.VersionedTransaction.deserialize(bufferData);
51
51
  tx.message.recentBlockhash = blockhash;
52
- const simulation = this.public.simulateTransaction(tx, {
53
- commitment: 'finalized',
54
- replaceRecentBlockhash: false,
55
- sigVerify: true,
56
- accounts: { encoding: 'base64', addresses: [...Object.values(config.accounts)] }
57
- });
52
+ // const simulation = this.public.simulateTransaction(tx, {
53
+ // commitment: 'finalized',
54
+ // replaceRecentBlockhash: false,
55
+ // sigVerify: true,
56
+ // accounts: { encoding: 'base64', addresses: [...Object.values(config.accounts)] }
57
+ // });
58
+ if (config.estimateConsumedUnits) {
59
+ const txWithBlockHash = Buffer.from(tx.serialize()).toString('base64');
60
+ const [computedUnitsPrice, computedUnitsLimit] = await Promise.all([
61
+ this.gasService.getConsumedUnitsPrice(txWithBlockHash),
62
+ this.gasService.getConsumedUnitsLimit(txWithBlockHash)
63
+ ]);
64
+ this.updatePriorityFee(tx, computedUnitsPrice.toNumber(), computedUnitsLimit.toNumber());
65
+ }
66
+ const simulation = this.public.simulateTransaction(tx, { replaceRecentBlockhash: true });
58
67
  const resp = await Promise.race([
59
68
  simulation,
60
69
  new Promise((_, reject) => setTimeout(() => reject('Timeout'), timeout))
@@ -65,6 +74,29 @@ class SolanaAdapter extends abstract_adapter_1.AbstractAdapter {
65
74
  throw err;
66
75
  }
67
76
  }
77
+ updatePriorityFee(tx, computeUnitPrice, computeUnitLimit) {
78
+ const computeBudgetOfset = 1;
79
+ const computeUnitPriceData = tx.message.compiledInstructions[1].data;
80
+ const encodedPrice = this.encodeNumberToArrayLE(computeUnitPrice, 8);
81
+ for (let i = 0; i < encodedPrice.length; i++) {
82
+ computeUnitPriceData[i + computeBudgetOfset] = encodedPrice[i];
83
+ }
84
+ if (computeUnitLimit) {
85
+ const computeUnitLimitData = tx.message.compiledInstructions[0].data;
86
+ const encodedLimit = this.encodeNumberToArrayLE(computeUnitLimit, 4);
87
+ for (let i = 0; i < encodedLimit.length; i++) {
88
+ computeUnitLimitData[i + computeBudgetOfset] = encodedLimit[i];
89
+ }
90
+ }
91
+ }
92
+ encodeNumberToArrayLE(num, arraySize) {
93
+ const result = new Uint8Array(arraySize);
94
+ for (let i = 0; i < arraySize; i++) {
95
+ result[i] = Number(num & 0xff);
96
+ num >>= 8;
97
+ }
98
+ return result;
99
+ }
68
100
  async checkEnoughBalance(token, walletAddress) {
69
101
  const balance = await this.getBalance(walletAddress, token.address);
70
102
  return balance.gte(token.tokenAmount);
@@ -14,9 +14,15 @@ export declare class SolanaGasService {
14
14
  getConsumedUnitsLimit(txData: string): Promise<BigNumber>;
15
15
  /**
16
16
  * @param txData base64 or hex string
17
- * @returns wei ComputedUnitsPrice - like gasPrice in evm
17
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
18
18
  */
19
19
  getConsumedUnitsPrice(txData: string): Promise<BigNumber>;
20
+ /**
21
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
22
+ */
20
23
  private calculateCUPriceHelius;
24
+ /**
25
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
26
+ */
21
27
  private calculateCUPriceSolWeb3;
22
28
  }
@@ -27,13 +27,13 @@ class SolanaGasService {
27
27
  return resp.value.unitsConsumed ? new bignumber_js_1.default(resp.value.unitsConsumed * 1.2) : new bignumber_js_1.default(DEFAULT_CU_LIMIT);
28
28
  }
29
29
  catch (err) {
30
- console.error('Solana_simulateTransaction_Error ==> ', err);
30
+ console.error('[SolanaApiService_getConsumedUnitsLimit] err ==> ', err);
31
31
  return new bignumber_js_1.default(DEFAULT_CU_LIMIT);
32
32
  }
33
33
  }
34
34
  /**
35
35
  * @param txData base64 or hex string
36
- * @returns wei ComputedUnitsPrice - like gasPrice in evm
36
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
37
37
  */
38
38
  async getConsumedUnitsPrice(txData) {
39
39
  if (!this.HELIUS_API_KEY) {
@@ -46,28 +46,42 @@ class SolanaGasService {
46
46
  .reduce((acc, price) => (acc.gt(price) ? acc : price), new bignumber_js_1.default(0));
47
47
  return cuPrice;
48
48
  }
49
+ /**
50
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
51
+ */
49
52
  async calculateCUPriceHelius(txData) {
50
- const tx = (0, utility_funcs_1.convertB64DataToTx)(txData);
51
- const resp = await this.httpClient.post(`${this.HELIUS_API_URL}/?api-key=${this.HELIUS_API_KEY}`, {
52
- jsonrpc: '2.0',
53
- id: '1',
54
- method: 'getPriorityFeeEstimate',
55
- params: [
56
- {
57
- transaction: utils_1.base58.encode(tx.serialize()), // Pass the serialized transaction in Base58
58
- options: { priorityLevel: 'Medium' }
59
- }
60
- ]
61
- });
62
- return new bignumber_js_1.default(resp.result.priorityFeeEstimate);
53
+ try {
54
+ const tx = (0, utility_funcs_1.convertB64DataToTx)(txData);
55
+ const resp = await this.httpClient.post(`${this.HELIUS_API_URL}/?api-key=${this.HELIUS_API_KEY}`, {
56
+ jsonrpc: '2.0',
57
+ id: '1',
58
+ method: 'getPriorityFeeEstimate',
59
+ params: [
60
+ {
61
+ transaction: utils_1.base58.encode(tx.serialize()), // Pass the serialized transaction in Base58
62
+ options: { priorityLevel: 'Medium' }
63
+ }
64
+ ]
65
+ });
66
+ return new bignumber_js_1.default(resp.result.priorityFeeEstimate);
67
+ }
68
+ catch (err) {
69
+ console.error('[SolanaGasService_getConsumedUnitsPrice] err ==> ', err);
70
+ return new bignumber_js_1.default(0);
71
+ }
63
72
  }
73
+ /**
74
+ * @returns consumedUnitsPrice in micro-lamports(lamport * 10^-6)
75
+ */
64
76
  async calculateCUPriceSolWeb3() {
77
+ const BASE_FEE = 5_000;
65
78
  const resp = await this.connection.getRecentPrioritizationFees();
66
79
  const avgCUPrice = resp
67
80
  .reduce((acc, tx) => acc.plus(tx.prioritizationFee), new bignumber_js_1.default(0))
68
81
  .div(resp.length)
69
82
  .dp(0, bignumber_js_1.default.ROUND_CEIL);
70
- return avgCUPrice;
83
+ const cuPrice = new bignumber_js_1.default(Math.max(BASE_FEE, avgCUPrice.toNumber()));
84
+ return cuPrice;
71
85
  }
72
86
  }
73
87
  exports.SolanaGasService = SolanaGasService;