@evaafi/sdk 0.9.0-a → 0.9.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 (101) hide show
  1. package/dist/api/feeds.d.ts +15 -24
  2. package/dist/api/feeds.js +22 -49
  3. package/dist/api/math.d.ts +1 -1
  4. package/dist/api/math.js +55 -38
  5. package/dist/api/parser.d.ts +2 -2
  6. package/dist/api/parser.js +3 -3
  7. package/dist/api/parsers/PythOracleParser.d.ts +3 -3
  8. package/dist/api/parsers/PythOracleParser.js +2 -1
  9. package/dist/api/prices.js +2 -1
  10. package/dist/constants/general/index.d.ts +25 -11
  11. package/dist/constants/general/index.js +15 -1
  12. package/dist/constants/pools/mainnet.js +20 -18
  13. package/dist/constants/pools/testnet.js +14 -6
  14. package/dist/contracts/AbstractMaster.d.ts +239 -127
  15. package/dist/contracts/AbstractMaster.js +101 -16
  16. package/dist/contracts/ClassicMaster.d.ts +12 -12
  17. package/dist/contracts/PythMaster.d.ts +40 -24
  18. package/dist/contracts/PythMaster.js +61 -76
  19. package/dist/contracts/PythOracle.d.ts +16 -0
  20. package/dist/contracts/PythOracle.js +19 -0
  21. package/dist/contracts/index.d.ts +1 -0
  22. package/dist/contracts/index.js +1 -0
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/{prices → oracles}/Types.d.ts +0 -4
  26. package/dist/oracles/collectors/AbstractCollector.d.ts +10 -0
  27. package/dist/oracles/collectors/AbstractCollector.js +6 -0
  28. package/dist/oracles/collectors/ClassicCollector.d.ts +22 -0
  29. package/dist/oracles/collectors/ClassicCollector.js +192 -0
  30. package/dist/oracles/collectors/PythCollector.d.ts +27 -0
  31. package/dist/oracles/collectors/PythCollector.js +252 -0
  32. package/dist/oracles/collectors/index.d.ts +3 -0
  33. package/dist/oracles/collectors/index.js +19 -0
  34. package/dist/{prices → oracles}/index.d.ts +2 -3
  35. package/dist/{prices → oracles}/index.js +2 -3
  36. package/dist/oracles/prices/AbstractPrices.d.ts +33 -0
  37. package/dist/oracles/prices/AbstractPrices.js +40 -0
  38. package/dist/oracles/prices/ClassicPrices.d.ts +19 -0
  39. package/dist/oracles/prices/ClassicPrices.js +48 -0
  40. package/dist/oracles/prices/PythPrices.d.ts +18 -0
  41. package/dist/oracles/prices/PythPrices.js +32 -0
  42. package/dist/oracles/prices/index.d.ts +3 -0
  43. package/dist/oracles/prices/index.js +19 -0
  44. package/dist/{prices → oracles}/utils.d.ts +6 -1
  45. package/dist/{prices → oracles}/utils.js +10 -1
  46. package/dist/types/Master.d.ts +4 -5
  47. package/package.json +2 -3
  48. package/src/api/feeds.ts +24 -60
  49. package/src/api/math.ts +118 -90
  50. package/src/api/parser.ts +5 -5
  51. package/src/api/parsers/PythOracleParser.ts +6 -2
  52. package/src/api/prices.ts +2 -1
  53. package/src/constants/general/index.ts +16 -1
  54. package/src/constants/pools/mainnet.ts +20 -35
  55. package/src/constants/pools/testnet.ts +17 -8
  56. package/src/contracts/AbstractMaster.ts +272 -144
  57. package/src/contracts/ClassicMaster.ts +12 -12
  58. package/src/contracts/PythMaster.ts +130 -123
  59. package/src/contracts/PythOracle.ts +20 -0
  60. package/src/contracts/index.ts +2 -0
  61. package/src/index.ts +1 -1
  62. package/src/{prices → oracles}/Types.ts +0 -5
  63. package/src/oracles/collectors/AbstractCollector.ts +22 -0
  64. package/src/oracles/collectors/ClassicCollector.ts +263 -0
  65. package/src/oracles/collectors/PythCollector.ts +358 -0
  66. package/src/oracles/collectors/index.ts +3 -0
  67. package/src/{prices → oracles}/index.ts +2 -3
  68. package/src/oracles/prices/AbstractPrices.ts +59 -0
  69. package/src/oracles/prices/ClassicPrices.ts +52 -0
  70. package/src/oracles/prices/PythPrices.ts +40 -0
  71. package/src/oracles/prices/index.ts +3 -0
  72. package/src/{prices → oracles}/utils.ts +12 -1
  73. package/src/types/Master.ts +4 -6
  74. package/dist/prices/Oracle.interface.d.ts +0 -9
  75. package/dist/prices/Oracle.interface.js +0 -2
  76. package/dist/prices/Prices.d.ts +0 -11
  77. package/dist/prices/Prices.js +0 -53
  78. package/dist/prices/PricesCollector.d.ts +0 -22
  79. package/dist/prices/PricesCollector.js +0 -146
  80. package/dist/prices/PythCollector.d.ts +0 -22
  81. package/dist/prices/PythCollector.js +0 -217
  82. package/src/prices/Oracle.interface.ts +0 -18
  83. package/src/prices/Prices.ts +0 -45
  84. package/src/prices/PricesCollector.ts +0 -169
  85. package/src/prices/PythCollector.ts +0 -294
  86. /package/dist/{prices → oracles}/Types.js +0 -0
  87. /package/dist/{prices → oracles}/constants.d.ts +0 -0
  88. /package/dist/{prices → oracles}/constants.js +0 -0
  89. /package/dist/{prices → oracles}/sources/Backend.d.ts +0 -0
  90. /package/dist/{prices → oracles}/sources/Backend.js +0 -0
  91. /package/dist/{prices → oracles}/sources/Icp.d.ts +0 -0
  92. /package/dist/{prices → oracles}/sources/Icp.js +0 -0
  93. /package/dist/{prices → oracles}/sources/PriceSource.d.ts +0 -0
  94. /package/dist/{prices → oracles}/sources/PriceSource.js +0 -0
  95. /package/dist/{prices → oracles}/sources/index.d.ts +0 -0
  96. /package/dist/{prices → oracles}/sources/index.js +0 -0
  97. /package/src/{prices → oracles}/constants.ts +0 -0
  98. /package/src/{prices → oracles}/sources/Backend.ts +0 -0
  99. /package/src/{prices → oracles}/sources/Icp.ts +0 -0
  100. /package/src/{prices → oracles}/sources/PriceSource.ts +0 -0
  101. /package/src/{prices → oracles}/sources/index.ts +0 -0
@@ -9,38 +9,82 @@ const userJettonWallet_1 = require("../utils/userJettonWallet");
9
9
  const JettonWallet_1 = require("./JettonWallet");
10
10
  const UserContract_1 = require("./UserContract");
11
11
  /**
12
- * Abstract EVAA Master base that encapsulates shared logic and structure.
13
- * Concrete implementations (Classic/Pyth) should override message creation for
14
- * withdraw/liquidation and supply-withdraw wrapping.
12
+ * Abstract base class for EVAA Master contracts
13
+ *
14
+ * This class provides shared functionality for both Classic and Pyth master implementations,
15
+ * including message creation, validation, and transaction handling. Concrete implementations
16
+ * must override oracle-specific methods for withdraw/liquidation operations.
17
+ *
18
+ * @template T - Master data type extending MasterData with specific oracle configuration
19
+ * @abstract
20
+ * @implements {Contract}
15
21
  */
16
22
  class AbstractEvaaMaster {
23
+ /**
24
+ * Initialize the abstract master contract
25
+ * @param parameters - Configuration parameters for the Evaa master
26
+ */
17
27
  constructor(parameters) {
18
28
  this.lastSync = 0;
19
29
  this._poolConfig = parameters.poolConfig;
20
30
  this.address = this._poolConfig.masterAddress;
21
31
  this.debug = parameters?.debug;
22
32
  }
33
+ /**
34
+ * Get the current pool configuration
35
+ * @returns {PoolConfig} The pool configuration object
36
+ */
23
37
  get poolConfig() {
24
38
  return this._poolConfig;
25
39
  }
40
+ /**
41
+ * Get the synchronized master data
42
+ * @returns {T | undefined} Master data if available, undefined otherwise
43
+ */
26
44
  get data() {
27
45
  return this._data;
28
46
  }
29
- // ---------- Common helpers ----------
30
- createJettonTransferMessage(parameters, defaultFees, message) {
47
+ // ========== VALIDATION METHODS ==========
48
+ /**
49
+ * Validates jetton parameters ensuring at least one amount field is provided
50
+ * @private
51
+ * @static
52
+ * @param parameters - Jetton parameters to validate
53
+ * @returns {ValidJettonParams} Validated parameters
54
+ * @throws {Error} When no amount fields are provided
55
+ */
56
+ static validateJettonParams(parameters) {
31
57
  if (parameters.amount == undefined &&
32
58
  parameters.liquidationAmount == undefined &&
33
59
  parameters.supplyAmount == undefined) {
34
- throw new Error('Either amount or liquidationAmount or supplyAmount must be provided');
60
+ throw new Error(`JettonParams validation failed: ${general_1.VALIDATION.ERRORS.MISSING_JETTON_AMOUNT}`);
61
+ }
62
+ return parameters;
63
+ }
64
+ /**
65
+ * Creates a jetton transfer message with the provided parameters
66
+ * @protected
67
+ * @param parameters - Jetton transfer parameters
68
+ * @param defaultFees - Default fee amount for the operation
69
+ * @param message - Operation message cell to include
70
+ * @returns {Cell} Complete jetton transfer message cell
71
+ * @throws {Error} When validation fails or required addresses are missing
72
+ */
73
+ createJettonTransferMessage(parameters, defaultFees, message) {
74
+ const validParams = AbstractEvaaMaster.validateJettonParams(parameters);
75
+ const amount = validParams.amount ?? validParams.liquidationAmount ?? validParams.supplyAmount ?? 0n;
76
+ const responseAddress = validParams.responseAddress ?? validParams.userAddress ?? validParams.liquidatorAddress;
77
+ if (!responseAddress) {
78
+ throw new Error(`JettonTransfer validation failed: ${general_1.VALIDATION.ERRORS.MISSING_RESPONSE_ADDRESS}`);
35
79
  }
36
80
  return (0, core_1.beginCell)()
37
81
  .storeUint(general_1.OPCODES.JETTON_TRANSFER, 32)
38
- .storeUint(parameters.queryID, 64)
39
- .storeCoins(parameters.amount ?? parameters.liquidationAmount ?? parameters.supplyAmount ?? 0n)
40
- .storeAddress(parameters.destinationAddress ?? this.address)
41
- .storeAddress(parameters.responseAddress ?? parameters.userAddress ?? parameters.liquidatorAddress)
82
+ .storeUint(validParams.queryID, 64)
83
+ .storeCoins(amount)
84
+ .storeAddress(validParams.destinationAddress ?? this.address)
85
+ .storeAddress(responseAddress)
42
86
  .storeBit(0)
43
- .storeCoins(parameters.forwardAmount ?? defaultFees)
87
+ .storeCoins(validParams.forwardAmount ?? defaultFees)
44
88
  .storeBit(1)
45
89
  .storeRef(message)
46
90
  .endCell();
@@ -58,8 +102,27 @@ class AbstractEvaaMaster {
58
102
  const generalData = this.buildGeneralDataPayload(parameters);
59
103
  return (0, core_1.beginCell)().storeRef(supplyData).storeRef(withdrawData).storeRef(generalData).endCell();
60
104
  }
61
- // ---------- Public message builders (shared) ----------
105
+ // ========== MESSAGE BUILDERS ==========
106
+ /**
107
+ * Validates supply operation parameters
108
+ * @private
109
+ * @static
110
+ * @param parameters - Supply parameters to validate
111
+ * @throws {Error} When amount is invalid or subaccount ID is out of range
112
+ */
113
+ static validateSupplyParameters(parameters) {
114
+ if (parameters.subaccountId !== undefined && !(0, __1.isValidSubaccountId)(parameters.subaccountId)) {
115
+ throw new Error(`Supply validation failed: ${general_1.VALIDATION.ERRORS.INVALID_SUBACCOUNT_ID}`);
116
+ }
117
+ }
118
+ /**
119
+ * Creates a supply operation message
120
+ * @param parameters - Supply operation parameters
121
+ * @returns {Cell} Complete supply message cell
122
+ * @throws {Error} When validation fails
123
+ */
62
124
  createSupplyMessage(parameters) {
125
+ AbstractEvaaMaster.validateSupplyParameters(parameters);
63
126
  const subaccountId = parameters.subaccountId ?? 0;
64
127
  const isTon = (0, __1.isTonAsset)(parameters.asset);
65
128
  const operationPayload = (0, core_1.beginCell)()
@@ -81,7 +144,15 @@ class AbstractEvaaMaster {
81
144
  return operationPayload;
82
145
  }
83
146
  }
84
- // ---------- Sending operations ----------
147
+ // ========== TRANSACTION OPERATIONS ==========
148
+ /**
149
+ * Sends a supply operation to the master contract
150
+ * @param provider - Contract provider instance
151
+ * @param via - Sender instance
152
+ * @param value - Transaction value in nanoTON
153
+ * @param parameters - Supply operation parameters
154
+ * @throws {Error} When validation fails or transaction fails
155
+ */
85
156
  async sendSupply(provider, via, value, parameters) {
86
157
  const message = this.createSupplyMessage(parameters);
87
158
  await this.sendTx(provider, via, value, message, parameters.asset);
@@ -106,7 +177,15 @@ class AbstractEvaaMaster {
106
177
  .storeInt(parameters.includeUserCode ? -1 : 0, 2)
107
178
  .storeUint((0, __1.isTonAsset)(parameters.asset) ? parameters.liquidationAmount : 0, 64);
108
179
  }
109
- // ---------- Read helpers ----------
180
+ // ========== CONTRACT INTERACTION HELPERS ==========
181
+ /**
182
+ * Calculates the user smart contract address for a given user and subaccount
183
+ * @param userAddress - The user's wallet address
184
+ * @param lendingCode - The user contract code cell
185
+ * @param subaccountId - Optional subaccount identifier (default: 0)
186
+ * @returns {Address} The calculated user contract address
187
+ * @throws {Error} When subaccount ID is invalid
188
+ */
110
189
  calculateUserSCAddr(userAddress, lendingCode, subaccountId = 0) {
111
190
  const subaccount = (0, core_1.beginCell)();
112
191
  if (subaccountId !== 0) {
@@ -129,6 +208,12 @@ class AbstractEvaaMaster {
129
208
  .endCell();
130
209
  return new core_1.Address(0, stateInit.hash());
131
210
  }
211
+ /**
212
+ * Creates a user contract instance for the given address and subaccount
213
+ * @param userAddress - The user's wallet address
214
+ * @param subaccountId - Optional subaccount identifier (default: 0)
215
+ * @returns {EvaaUser} User contract instance
216
+ */
132
217
  openUserContract(userAddress, subaccountId = 0) {
133
218
  return UserContract_1.EvaaUser.createFromAddress(this.calculateUserSCAddr(userAddress, this._poolConfig.lendingCode, subaccountId), this._poolConfig);
134
219
  }
@@ -167,12 +252,12 @@ class AbstractEvaaMaster {
167
252
  if (state.type === 'active') {
168
253
  this._data = (0, parser_1.parseMasterData)(state.data.toString('base64'), this._poolConfig.poolAssetsConfig, this._poolConfig.masterConstants, oracleParser);
169
254
  if (this._data.upgradeConfig.masterCodeVersion !== this._poolConfig.masterVersion) {
170
- throw Error(`Outdated SDK pool version. It supports only master code version ${this._poolConfig.masterVersion}, but the current master code version is ${this._data.upgradeConfig.masterCodeVersion}`);
255
+ throw new Error(`${general_1.VALIDATION.ERRORS.OUTDATED_SDK_VERSION}. SDK supports version ${this._poolConfig.masterVersion}, but contract version is ${this._data.upgradeConfig.masterCodeVersion}`);
171
256
  }
172
257
  this.lastSync = Math.floor(Date.now() / 1000);
173
258
  }
174
259
  else {
175
- throw Error('Master contract is not active');
260
+ throw new Error(general_1.VALIDATION.ERRORS.MASTER_CONTRACT_INACTIVE);
176
261
  }
177
262
  }
178
263
  }
@@ -2,26 +2,26 @@ import { Builder, Cell, ContractProvider, Sender } from '@ton/core';
2
2
  import { LiquidationParameters } from '..';
3
3
  import { ClassicOracleInfo } from '../api/parsers/ClassicOracleParser';
4
4
  import { AbstractEvaaMaster, BaseMasterConfig, BaseMasterData, EvaaParameters, LiquidationInnerParameters, LiquidationOperationBuilderParameters, SupplyWithdrawParameters, WithdrawParameters } from './AbstractMaster';
5
- export type ClassicSupplyWithdrawParameters = SupplyWithdrawParameters & {
6
- priceData?: Cell;
7
- };
5
+ export interface ClassicSupplyWithdrawParameters extends SupplyWithdrawParameters {
6
+ readonly priceData?: Cell;
7
+ }
8
8
  /**
9
9
  * Parameters for the withdraw message
10
10
  * @property priceData - price data cell. Can be obtained from the getPrices function
11
11
  */
12
- export type ClassicWithdrawParameters = WithdrawParameters & {
13
- priceData: Cell;
14
- };
12
+ export interface ClassicWithdrawParameters extends WithdrawParameters {
13
+ readonly priceData?: Cell;
14
+ }
15
15
  export type ClassicLiquidationOperationParameters = LiquidationOperationBuilderParameters & LiquidationInnerParameters & {
16
16
  priceData: Cell;
17
17
  };
18
18
  export type ClassicLiquidationParameters = LiquidationParameters & ClassicLiquidationOperationParameters;
19
- export type ClassicMasterConfig = BaseMasterConfig & {
20
- oraclesInfo: ClassicOracleInfo;
21
- };
22
- export type ClassicMasterData = BaseMasterData & {
23
- masterConfig: ClassicMasterConfig;
24
- };
19
+ export interface ClassicMasterConfig extends BaseMasterConfig {
20
+ readonly oraclesInfo: ClassicOracleInfo;
21
+ }
22
+ export interface ClassicMasterData extends BaseMasterData {
23
+ readonly masterConfig: ClassicMasterConfig;
24
+ }
25
25
  export declare class EvaaMasterClassic extends AbstractEvaaMaster<ClassicMasterData> {
26
26
  constructor(parameters: EvaaParameters);
27
27
  buildGeneralDataPayload(parameters: ClassicSupplyWithdrawParameters): Cell;
@@ -3,26 +3,29 @@
3
3
  import { HexString } from '@pythnetwork/hermes-client';
4
4
  import { Address, Cell, ContractProvider, Dictionary, Sender } from '@ton/core';
5
5
  import { PythOracleInfo } from '../api/parsers/PythOracleParser';
6
+ import { PoolAssetConfig } from '../types/Master';
6
7
  import { AbstractEvaaMaster, BaseMasterConfig, BaseMasterData, EvaaParameters, LiquidationInnerParameters, LiquidationOperationBuilderParameters, LiquidationParameters, SupplyWithdrawParameters, WithdrawParameters } from './AbstractMaster';
7
8
  /**
8
9
  * pyth specific parameters
9
10
  */
10
- export type PythBaseData = {
11
- priceData: Buffer | Cell;
12
- targetFeeds: HexString[];
13
- requestedRefTokens: bigint[];
14
- };
15
- export type ProxySpecificPythParams = {
16
- pythAddress: Address;
17
- minPublishTime: number | bigint;
18
- maxPublishTime: number | bigint;
19
- };
20
- export type OnchainSpecificPythParams = {
21
- publishGap: number | bigint;
22
- maxStaleness: number | bigint;
23
- };
24
- export type JettonPythParams = PythBaseData & OnchainSpecificPythParams;
25
- export type TonPythParams = PythBaseData & ProxySpecificPythParams;
11
+ export interface PythBaseData {
12
+ readonly priceData: Buffer | Cell;
13
+ readonly targetFeeds: HexString[];
14
+ readonly refAssets: PoolAssetConfig[];
15
+ }
16
+ export interface ProxySpecificPythParams {
17
+ readonly pythAddress: Address;
18
+ readonly minPublishTime: number | bigint;
19
+ readonly maxPublishTime: number | bigint;
20
+ }
21
+ export interface OnchainSpecificPythParams {
22
+ readonly publishGap: number | bigint;
23
+ readonly maxStaleness: number | bigint;
24
+ }
25
+ export interface JettonPythParams extends PythBaseData, OnchainSpecificPythParams {
26
+ }
27
+ export interface TonPythParams extends PythBaseData, ProxySpecificPythParams {
28
+ }
26
29
  export type PythProxyParams = {
27
30
  pyth: PythBaseData & (ProxySpecificPythParams | OnchainSpecificPythParams) & {
28
31
  pythAddress: Address;
@@ -30,16 +33,16 @@ export type PythProxyParams = {
30
33
  };
31
34
  export type PythSupplyWithdrawParameters = SupplyWithdrawParameters & Partial<PythProxyParams>;
32
35
  export type PythWithdrawParameters = WithdrawParameters & {
33
- pyth: TonPythParams;
36
+ pyth?: TonPythParams;
34
37
  };
35
38
  export type PythLiquidationOperationParameters = LiquidationOperationBuilderParameters & LiquidationInnerParameters & PythProxyParams;
36
39
  export type PythLiquidationParameters = LiquidationParameters & PythLiquidationOperationParameters;
37
- export type PythMasterConfig = BaseMasterConfig & {
38
- oraclesInfo: PythOracleInfo;
39
- };
40
- export type PythMasterData = BaseMasterData & {
41
- masterConfig: PythMasterConfig;
42
- };
40
+ export interface PythMasterConfig extends BaseMasterConfig {
41
+ readonly oraclesInfo: PythOracleInfo;
42
+ }
43
+ export interface PythMasterData extends BaseMasterData {
44
+ readonly masterConfig: PythMasterConfig;
45
+ }
43
46
  export declare class EvaaMasterPyth extends AbstractEvaaMaster<PythMasterData> {
44
47
  constructor(parameters: EvaaParameters);
45
48
  protected buildPythMasterMessage(args: {
@@ -51,8 +54,21 @@ export declare class EvaaMasterPyth extends AbstractEvaaMaster<PythMasterData> {
51
54
  maxStaleness: number | bigint;
52
55
  }, operationPayload: Cell): Cell;
53
56
  protected buildPythProxyMessage(targetAddress: Address, priceUpdateData: Cell, targetPythFeeds: Cell, minPublishTime: number | bigint, maxPublishTime: number | bigint, operationPayload: Cell): Cell;
57
+ /**
58
+ * Creates a wrapped operation payload for TON assets
59
+ */
60
+ private createWrappedOperationPayload;
61
+ /**
62
+ * Creates a jetton transfer message with pyth data
63
+ */
64
+ private createJettonPythMessage;
65
+ /**
66
+ * Creates a TON pyth proxy message
67
+ */
68
+ private createTonPythMessage;
69
+ protected createSupplyWithdrawMessageNoPrices(parameters: SupplyWithdrawParameters, operationPayload: Cell): Cell;
54
70
  createSupplyWithdrawMessage(parameters: PythSupplyWithdrawParameters): Cell;
55
- buildRefTokensDict(requestedRefTokens: bigint[]): Dictionary<bigint, Buffer>;
71
+ buildRefTokensDict(refAssets: PoolAssetConfig[]): Dictionary<bigint, Buffer>;
56
72
  buildGeneralDataPayload(parameters: PythSupplyWithdrawParameters): Cell;
57
73
  sendWithdraw(provider: ContractProvider, via: Sender, value: bigint, parameters: PythWithdrawParameters): Promise<void>;
58
74
  protected buildLiquidationOperationPayload(parameters: PythLiquidationOperationParameters): Cell;
@@ -36,73 +36,74 @@ class EvaaMasterPyth extends AbstractMaster_1.AbstractEvaaMaster {
36
36
  .storeRef(operationPayload)
37
37
  .endCell();
38
38
  }
39
- // TODO: support without OPCODES.SUPPLY_WITHDRAW_MASTER_WITHOUT_PRICES
40
- createSupplyWithdrawMessage(parameters) {
41
- const operationPayload = this.buildSupplyWithdrawOperationPayload(parameters);
39
+ /**
40
+ * Creates a wrapped operation payload for TON assets
41
+ */
42
+ createWrappedOperationPayload(opCode, queryID, operationPayload) {
43
+ return (0, core_1.beginCell)().storeUint(opCode, 32).storeUint(queryID, 64).storeRef(operationPayload).endCell();
44
+ }
45
+ /**
46
+ * Creates a jetton transfer message with pyth data
47
+ */
48
+ createJettonPythMessage(parameters, operationPayload, pythParams, opCode) {
49
+ const { priceData, targetFeeds, publishGap, maxStaleness } = pythParams;
50
+ const masterMessage = this.buildPythMasterMessage({
51
+ queryId: parameters.queryID,
52
+ opCode,
53
+ updateDataCell: (0, prices_1.packPythUpdatesData)(priceData),
54
+ targetFeedsCell: (0, prices_1.composeFeedsCell)(targetFeeds),
55
+ publishGap,
56
+ maxStaleness,
57
+ }, operationPayload);
58
+ return this.createJettonTransferMessage(parameters, general_1.FEES.SUPPLY_WITHDRAW, masterMessage);
59
+ }
60
+ /**
61
+ * Creates a TON pyth proxy message
62
+ */
63
+ createTonPythMessage(parameters, operationPayload, pythParams, opCode) {
64
+ const { priceData, targetFeeds, minPublishTime, maxPublishTime } = pythParams;
65
+ const wrappedOperationPayload = this.createWrappedOperationPayload(opCode, parameters.queryID, operationPayload);
66
+ return this.buildPythProxyMessage(this.address, (0, prices_1.packPythUpdatesData)(priceData), (0, prices_1.composeFeedsCell)(targetFeeds), minPublishTime, maxPublishTime, wrappedOperationPayload);
67
+ }
68
+ createSupplyWithdrawMessageNoPrices(parameters, operationPayload) {
69
+ const messageBody = (0, core_1.beginCell)()
70
+ .storeUint(general_1.OPCODES.SUPPLY_WITHDRAW_MASTER_WITHOUT_PRICES, 32)
71
+ .storeSlice(operationPayload.beginParse())
72
+ .endCell();
42
73
  if (!(0, utils_1.isTonAsset)(parameters.supplyAsset)) {
43
- const { priceData, targetFeeds, publishGap, maxStaleness } = parameters.pyth;
44
- const masterMessage = this.buildPythMasterMessage({
45
- queryId: parameters.queryID,
46
- opCode: general_1.OPCODES.SUPPLY_WITHDRAW_MASTER_JETTON,
47
- updateDataCell: (0, prices_1.packPythUpdatesData)(priceData),
48
- targetFeedsCell: (0, prices_1.composeFeedsCell)(targetFeeds),
49
- publishGap,
50
- maxStaleness,
51
- }, operationPayload);
52
- return this.createJettonTransferMessage(parameters, general_1.FEES.SUPPLY_WITHDRAW, masterMessage);
74
+ return this.createJettonTransferMessage(parameters, general_1.FEES.SUPPLY_WITHDRAW + general_1.FEES.JETTON_FWD, messageBody);
53
75
  }
54
76
  else {
55
- const { priceData, targetFeeds, minPublishTime, maxPublishTime } = parameters.pyth;
56
- const wrappedOperationPayload = (0, core_1.beginCell)()
57
- .storeUint(general_1.OPCODES.SUPPLY_WITHDRAW_MASTER, 32)
77
+ return (0, core_1.beginCell)()
78
+ .storeUint(general_1.OPCODES.SUPPLY_WITHDRAW_MASTER_WITHOUT_PRICES, 32)
58
79
  .storeUint(parameters.queryID, 64)
59
- .storeRef(operationPayload)
80
+ .storeSlice(operationPayload.beginParse())
60
81
  .endCell();
61
- return this.buildPythProxyMessage(this.address, (0, prices_1.packPythUpdatesData)(priceData), (0, prices_1.composeFeedsCell)(targetFeeds), minPublishTime, maxPublishTime, wrappedOperationPayload);
62
82
  }
63
83
  }
64
- // private createPythWithdrawMessage(parameters: PythWithdrawParameters): Cell {
65
- // const extraTail =
66
- // (parameters.subaccountId ?? 0) == 0
67
- // ? beginCell().endCell()
68
- // : beginCell()
69
- // .storeInt(parameters.subaccountId ?? 0, 16)
70
- // .storeUint(0, 2)
71
- // .endCell();
72
- // const wrappedOperationPayload = beginCell()
73
- // .storeUint(OPCODES.SUPPLY_WITHDRAW_MASTER, 32) // op_code: 0x4
74
- // .storeUint(parameters.queryID, 64)
75
- // .storeRef(
76
- // beginCell()
77
- // .storeUint(parameters.asset.assetId, 256)
78
- // .storeUint(parameters.amount, 64)
79
- // .storeAddress(parameters.userAddress)
80
- // .storeInt(parameters.includeUserCode ? -1 : 0, 2)
81
- // .storeUint(parameters.amountToTransfer, 64)
82
- // .storeRef(parameters.payload)
83
- // .storeSlice(extraTail.beginParse())
84
- // .endCell(),
85
- // )
86
- // .endCell();
87
- // const { priceData, targetFeeds, minPublishTime, maxPublishTime } = parameters.pyth as TonPythParams;
88
- // return makePythProxyMessage(
89
- // this.address,
90
- // packPythUpdatesData(priceData),
91
- // composeFeedsCell(targetFeeds),
92
- // minPublishTime,
93
- // maxPublishTime,
94
- // wrappedOperationPayload,
95
- // );
96
- // }
97
- buildRefTokensDict(requestedRefTokens) {
84
+ createSupplyWithdrawMessage(parameters) {
85
+ const operationPayload = this.buildSupplyWithdrawOperationPayload(parameters);
86
+ // Handle case without pyth data
87
+ if (!parameters.pyth) {
88
+ return this.createSupplyWithdrawMessageNoPrices(parameters, operationPayload);
89
+ }
90
+ if (!(0, utils_1.isTonAsset)(parameters.supplyAsset)) {
91
+ return this.createJettonPythMessage(parameters, // as JettonParams & { queryID: number | bigint },
92
+ operationPayload, parameters.pyth, general_1.OPCODES.SUPPLY_WITHDRAW_MASTER_JETTON);
93
+ }
94
+ else {
95
+ return this.createTonPythMessage(parameters, operationPayload, parameters.pyth, general_1.OPCODES.SUPPLY_WITHDRAW_MASTER);
96
+ }
97
+ }
98
+ buildRefTokensDict(refAssets) {
98
99
  const refsDict = core_1.Dictionary.empty(core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.Buffer(0));
99
- for (const refToken of requestedRefTokens) {
100
- refsDict.set(refToken, Buffer.alloc(0));
100
+ for (const refAsset of refAssets) {
101
+ refsDict.set(refAsset.assetId, Buffer.alloc(0));
101
102
  }
102
103
  return refsDict;
103
104
  }
104
105
  buildGeneralDataPayload(parameters) {
105
- const refTokensDict = this.buildRefTokensDict(parameters.pyth?.requestedRefTokens ?? []);
106
+ const refTokensDict = this.buildRefTokensDict(parameters.pyth?.refAssets ?? []);
106
107
  return (0, core_1.beginCell)()
107
108
  .storeInt(parameters.includeUserCode ? -1 : 0, 2)
108
109
  .storeDict(refTokensDict, core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.Buffer(0))
@@ -132,7 +133,7 @@ class EvaaMasterPyth extends AbstractMaster_1.AbstractEvaaMaster {
132
133
  });
133
134
  await via.send({
134
135
  value,
135
- to: parameters.pyth.pythAddress,
136
+ to: parameters.pyth?.pythAddress ?? this.address,
136
137
  sendMode: core_1.SendMode.PAY_GAS_SEPARATELY + core_1.SendMode.IGNORE_ERRORS,
137
138
  body: message,
138
139
  });
@@ -140,32 +141,16 @@ class EvaaMasterPyth extends AbstractMaster_1.AbstractEvaaMaster {
140
141
  buildLiquidationOperationPayload(parameters) {
141
142
  const operationPayloadBuilder = this.buildLiquidationOperationPayloadBuilder(parameters);
142
143
  const innerBuilder = this.buildLiquidationInnerBuilder(parameters);
143
- const refTokensDict = this.buildRefTokensDict(parameters.pyth.requestedRefTokens);
144
+ const refTokensDict = this.buildRefTokensDict(parameters.pyth.refAssets);
144
145
  return operationPayloadBuilder.storeDict(refTokensDict).storeRef(innerBuilder).endCell();
145
146
  }
146
147
  createLiquidationMessage(parameters) {
147
- const isTon = (0, utils_1.isTonAsset)(parameters.asset);
148
148
  const operationPayload = this.buildLiquidationOperationPayload(parameters);
149
- if (!isTon) {
150
- const { priceData, targetFeeds, publishGap, maxStaleness } = parameters.pyth;
151
- const masterMessage = this.buildPythMasterMessage({
152
- queryId: parameters.queryID,
153
- opCode: general_1.OPCODES.LIQUIDATE_MASTER,
154
- updateDataCell: (0, prices_1.packPythUpdatesData)(priceData),
155
- targetFeedsCell: (0, prices_1.composeFeedsCell)(targetFeeds),
156
- publishGap,
157
- maxStaleness,
158
- }, operationPayload);
159
- return this.createJettonTransferMessage(parameters, general_1.FEES.LIQUIDATION_JETTON_FWD, masterMessage);
149
+ if (!(0, utils_1.isTonAsset)(parameters.asset)) {
150
+ return this.createJettonPythMessage(parameters, operationPayload, parameters.pyth, general_1.OPCODES.LIQUIDATE_MASTER);
160
151
  }
161
152
  else {
162
- const { priceData, targetFeeds, minPublishTime, maxPublishTime } = parameters.pyth;
163
- const wrappedOperationPayload = (0, core_1.beginCell)()
164
- .storeUint(general_1.OPCODES.LIQUIDATE_MASTER, 32)
165
- .storeUint(parameters.queryID, 64)
166
- .storeRef(operationPayload)
167
- .endCell();
168
- return this.buildPythProxyMessage(this.address, (0, prices_1.packPythUpdatesData)(priceData), (0, prices_1.composeFeedsCell)(targetFeeds), minPublishTime, maxPublishTime, wrappedOperationPayload);
153
+ return this.createTonPythMessage(parameters, operationPayload, parameters.pyth, general_1.OPCODES.LIQUIDATE_MASTER);
169
154
  }
170
155
  }
171
156
  async sendLiquidation(provider, via, value, parameters) {
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Address, Cell, Contract, ContractProvider } from '@ton/core';
4
+ export declare class PythOracle implements Contract {
5
+ readonly address: Address;
6
+ readonly init?: {
7
+ code: Cell;
8
+ data: Cell;
9
+ } | undefined;
10
+ constructor(address: Address, init?: {
11
+ code: Cell;
12
+ data: Cell;
13
+ } | undefined);
14
+ static createFromAddress(address: Address): PythOracle;
15
+ getUpdateFee(provider: ContractProvider, vm: Buffer): Promise<bigint>;
16
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PythOracle = void 0;
4
+ const pyth_ton_js_1 = require("@pythnetwork/pyth-ton-js");
5
+ class PythOracle {
6
+ constructor(address, init) {
7
+ this.address = address;
8
+ this.init = init;
9
+ }
10
+ static createFromAddress(address) {
11
+ return new this(address);
12
+ }
13
+ async getUpdateFee(provider, vm) {
14
+ const result = await provider.get('get_update_fee', [{ type: 'slice', cell: (0, pyth_ton_js_1.createCellChain)(vm) }]);
15
+ const numUpdates = result.stack.readNumber();
16
+ return (0, pyth_ton_js_1.calculateUpdatePriceFeedsFee)(BigInt(numUpdates)) + BigInt(numUpdates);
17
+ }
18
+ }
19
+ exports.PythOracle = PythOracle;
@@ -3,3 +3,4 @@ export * from './ClassicMaster';
3
3
  export * from './PythMaster';
4
4
  export * from './UserContract';
5
5
  export * from './JettonWallet';
6
+ export * from './PythOracle';
@@ -19,3 +19,4 @@ __exportStar(require("./ClassicMaster"), exports);
19
19
  __exportStar(require("./PythMaster"), exports);
20
20
  __exportStar(require("./UserContract"), exports);
21
21
  __exportStar(require("./JettonWallet"), exports);
22
+ __exportStar(require("./PythOracle"), exports);
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export * from './types/User';
17
17
  export * from './constants/general';
18
18
  export * from './constants/pools';
19
19
  export * from './constants/assets';
20
- export * from './prices';
20
+ export * from './oracles';
21
21
  export * from './utils/utils';
22
22
  export { getLastSentBoc, getTonConnectSender } from './utils/tonConnectSender';
23
23
  export { getUserJettonWallet } from './utils/userJettonWallet';
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ __exportStar(require("./types/User"), exports);
46
46
  __exportStar(require("./constants/general"), exports);
47
47
  __exportStar(require("./constants/pools"), exports);
48
48
  __exportStar(require("./constants/assets"), exports);
49
- __exportStar(require("./prices"), exports);
49
+ __exportStar(require("./oracles"), exports);
50
50
  __exportStar(require("./utils/utils"), exports);
51
51
  // Utils
52
52
  var tonConnectSender_1 = require("./utils/tonConnectSender");
@@ -38,10 +38,6 @@ export type PythFeedUpdateType = {
38
38
  parsed: PriceUpdate['parsed'];
39
39
  binary: Buffer;
40
40
  };
41
- export type PriceData = {
42
- dict: Dictionary<bigint, bigint>;
43
- dataCell: Cell;
44
- };
45
41
  export type OraclePricesData = {
46
42
  timestamp: number;
47
43
  prices: Dictionary<bigint, bigint>;
@@ -0,0 +1,10 @@
1
+ import { Dictionary } from '@ton/core';
2
+ import { PoolAssetConfig } from '../../types/Master';
3
+ import { FetchConfig } from '../../utils/utils';
4
+ import { ClassicPrices } from '../prices/ClassicPrices';
5
+ import { PythPrices } from '../prices/PythPrices';
6
+ export declare abstract class AbstractCollector {
7
+ abstract getPricesForLiquidate(realPrincipals: Dictionary<bigint, bigint>, fetchConfig?: FetchConfig): Promise<ClassicPrices | PythPrices>;
8
+ abstract getPricesForSupplyWithdraw(realPrincipals: Dictionary<bigint, bigint>, supplyAsset: PoolAssetConfig | undefined, withdrawAsset: PoolAssetConfig | undefined, collateralToDebt: boolean, fetchConfig?: FetchConfig): Promise<ClassicPrices | PythPrices>;
9
+ abstract getPrices(assets: PoolAssetConfig[], fetchConfig?: FetchConfig): Promise<ClassicPrices | PythPrices>;
10
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractCollector = void 0;
4
+ class AbstractCollector {
5
+ }
6
+ exports.AbstractCollector = AbstractCollector;
@@ -0,0 +1,22 @@
1
+ import { Dictionary } from '@ton/core';
2
+ import { ExtendedEvaaOracle, PoolAssetConfig } from '../../types/Master';
3
+ import { FetchConfig } from '../../utils/utils';
4
+ import { ClassicPrices } from '../prices/ClassicPrices';
5
+ import { PriceSource } from '../sources';
6
+ import { PriceSourcesConfig } from '../Types';
7
+ import { AbstractCollector } from './AbstractCollector';
8
+ export type ClassicCollectorConfig = {
9
+ poolAssetsConfig: PoolAssetConfig[];
10
+ minimalOracles: number;
11
+ evaaOracles: ExtendedEvaaOracle[];
12
+ sourcesConfig?: PriceSourcesConfig;
13
+ additionalPriceSources?: PriceSource[];
14
+ };
15
+ export declare class ClassicCollector extends AbstractCollector {
16
+ #private;
17
+ constructor(config: ClassicCollectorConfig);
18
+ getPricesForLiquidate(realPrincipals: Dictionary<bigint, bigint>, fetchConfig?: FetchConfig): Promise<ClassicPrices>;
19
+ getPricesForWithdraw(realPrincipals: Dictionary<bigint, bigint>, withdrawAsset: PoolAssetConfig, collateralToDebt?: boolean, fetchConfig?: FetchConfig): Promise<ClassicPrices>;
20
+ getPricesForSupplyWithdraw(realPrincipals: Dictionary<bigint, bigint>, supplyAsset: PoolAssetConfig | undefined, withdrawAsset: PoolAssetConfig | undefined, collateralToDebt: boolean, fetchConfig?: FetchConfig): Promise<ClassicPrices>;
21
+ getPrices(assets?: PoolAssetConfig[], fetchConfig?: FetchConfig): Promise<ClassicPrices>;
22
+ }