@scallop-io/sui-scallop-sdk 3.0.2 → 4.1.0

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 (283) hide show
  1. package/dist/Logger-Cg2iFdpH.d.ts +8 -0
  2. package/dist/builder.cjs +22 -0
  3. package/dist/builder.d.cts +28 -0
  4. package/dist/builder.d.ts +28 -0
  5. package/dist/builder.js +4 -0
  6. package/dist/chunk-33AK5RWM.js +15 -0
  7. package/dist/chunk-6UQ4NWEU.js +3 -0
  8. package/dist/chunk-DIC6P5HB.js +11 -0
  9. package/dist/chunk-S34VOEZN.js +3 -0
  10. package/dist/chunk-VTGQACWU.js +6 -0
  11. package/dist/client.cjs +21 -0
  12. package/dist/client.d.cts +401 -0
  13. package/dist/client.d.ts +401 -0
  14. package/dist/client.js +5 -0
  15. package/dist/errors.cjs +10 -0
  16. package/dist/errors.d.cts +32 -0
  17. package/dist/errors.d.ts +32 -0
  18. package/dist/errors.js +1 -0
  19. package/dist/index.cjs +51 -34
  20. package/dist/index.d.cts +130 -3145
  21. package/dist/index.d.ts +130 -3145
  22. package/dist/index.js +8 -12
  23. package/dist/logger.cjs +6 -0
  24. package/dist/logger.d.cts +7 -0
  25. package/dist/logger.d.ts +7 -0
  26. package/dist/logger.js +1 -0
  27. package/dist/query-DkitepDi.d.ts +3305 -0
  28. package/dist/query.cjs +19 -0
  29. package/dist/query.d.cts +9 -0
  30. package/dist/query.d.ts +9 -0
  31. package/dist/query.js +3 -0
  32. package/dist/types.cjs +2 -0
  33. package/dist/types.d.cts +90 -0
  34. package/dist/types.d.ts +90 -0
  35. package/dist/types.js +1 -0
  36. package/package.json +98 -56
  37. package/src/constants/api.ts +2 -0
  38. package/src/constants/coinType.ts +2 -0
  39. package/src/constants/common.ts +0 -7
  40. package/src/constants/index.ts +2 -0
  41. package/src/constants/queryKeys.ts +14 -7
  42. package/src/constants/testAddress.ts +1 -0
  43. package/src/datasources/api.ts +34 -0
  44. package/src/datasources/indexer.ts +8 -0
  45. package/src/datasources/onchain.ts +121 -0
  46. package/src/entries/builder.ts +5 -0
  47. package/src/entries/client.ts +3 -0
  48. package/src/entries/errors.ts +2 -0
  49. package/src/entries/index.ts +17 -0
  50. package/src/entries/logger.ts +2 -0
  51. package/src/entries/query.ts +6 -0
  52. package/src/entries/types.ts +2 -0
  53. package/src/errors/ScallopConfigError.ts +8 -0
  54. package/src/errors/ScallopError.ts +30 -0
  55. package/src/errors/ScallopIndexerError.ts +8 -0
  56. package/src/errors/ScallopParseError.ts +8 -0
  57. package/src/errors/ScallopRpcError.ts +8 -0
  58. package/src/errors/ScallopTransactionBuildError.ts +8 -0
  59. package/src/errors/index.ts +6 -0
  60. package/src/logger/Logger.ts +6 -0
  61. package/src/logger/consoleLogger.ts +13 -0
  62. package/src/logger/index.ts +3 -0
  63. package/src/logger/noopLogger.ts +8 -0
  64. package/src/mappers/index.ts +1 -0
  65. package/src/mappers/moveTypeMapper.ts +48 -0
  66. package/src/models/index.ts +8 -10
  67. package/src/models/interface.ts +9 -9
  68. package/src/models/scallop.ts +9 -16
  69. package/src/models/scallopAddress/const.ts +416 -0
  70. package/src/models/scallopAddress/index.ts +188 -0
  71. package/src/models/scallopAddress/types.ts +212 -0
  72. package/src/models/{scallopBuilder.ts → scallopBuilder/index.ts} +65 -29
  73. package/src/models/scallopBuilder/types.ts +37 -0
  74. package/src/models/{scallopClient.ts → scallopClient/index.ts} +157 -598
  75. package/src/models/scallopClient/types.ts +25 -0
  76. package/src/models/scallopConstants/config/AddressConfigSource.ts +13 -0
  77. package/src/models/scallopConstants/config/ConfigValidator.ts +70 -0
  78. package/src/models/scallopConstants/config/PoolAddressConfigSource.ts +12 -0
  79. package/src/models/scallopConstants/config/ScallopConfig.ts +80 -0
  80. package/src/models/scallopConstants/config/ScallopConfigSnapshot.ts +46 -0
  81. package/src/models/scallopConstants/config/WhitelistConfigSource.ts +16 -0
  82. package/src/models/scallopConstants/config/index.ts +6 -0
  83. package/src/models/scallopConstants/const.ts +19 -0
  84. package/src/models/scallopConstants/constantsSource.ts +98 -0
  85. package/src/models/scallopConstants/deriveConstants.ts +150 -0
  86. package/src/models/scallopConstants/index.ts +257 -0
  87. package/src/models/scallopConstants/loadConstantsState.ts +135 -0
  88. package/src/models/scallopConstants/types.ts +77 -0
  89. package/src/models/scallopConstants/utils.ts +69 -0
  90. package/src/models/scallopQuery/index.ts +1279 -0
  91. package/src/models/scallopQuery/types.ts +9 -0
  92. package/src/models/scallopQuery/utils.ts +13 -0
  93. package/src/models/scallopUtils/index.ts +505 -0
  94. package/src/models/scallopUtils/types.ts +30 -0
  95. package/src/models/transactionExecutor.ts +122 -0
  96. package/src/repositories/addressApi/helpers.ts +14 -0
  97. package/src/repositories/addressApi/index.ts +24 -0
  98. package/src/repositories/addressApi/schema.ts +0 -0
  99. package/src/repositories/addressApi/types.ts +177 -0
  100. package/src/repositories/base.ts +38 -0
  101. package/src/repositories/borrowIncentive/bcs.ts +11 -0
  102. package/src/repositories/borrowIncentive/helpers.ts +396 -0
  103. package/src/repositories/borrowIncentive/index.ts +52 -0
  104. package/src/{types/query/borrowIncentive.ts → repositories/borrowIncentive/types.ts} +69 -23
  105. package/src/repositories/borrowIncentive/utils.ts +234 -0
  106. package/src/repositories/cache.ts +4 -0
  107. package/src/repositories/coinBalance/helpers.ts +394 -0
  108. package/src/repositories/coinBalance/index.ts +69 -0
  109. package/src/repositories/coinBalance/types.ts +33 -0
  110. package/src/repositories/flashloan/const.ts +3 -0
  111. package/src/repositories/flashloan/helpers.ts +107 -0
  112. package/src/repositories/flashloan/index.ts +34 -0
  113. package/src/repositories/flashloan/types.ts +16 -0
  114. package/src/repositories/isolatedAssets/bcs.ts +4 -0
  115. package/src/repositories/isolatedAssets/const.ts +2 -0
  116. package/src/repositories/isolatedAssets/helpers.ts +91 -0
  117. package/src/repositories/isolatedAssets/index.ts +42 -0
  118. package/src/repositories/isolatedAssets/types.ts +35 -0
  119. package/src/repositories/loyaltyProgram/bcs.ts +7 -0
  120. package/src/repositories/loyaltyProgram/helpers.ts +117 -0
  121. package/src/repositories/loyaltyProgram/index.ts +28 -0
  122. package/src/repositories/loyaltyProgram/schema.ts +18 -0
  123. package/src/repositories/loyaltyProgram/types.ts +37 -0
  124. package/src/repositories/market/const.ts +6 -0
  125. package/src/repositories/market/helpers.ts +740 -0
  126. package/src/repositories/market/index.ts +137 -0
  127. package/src/repositories/market/mapper.ts +30 -0
  128. package/src/repositories/market/types.ts +443 -0
  129. package/src/repositories/market/utils.ts +285 -0
  130. package/src/repositories/obligation/helpers.ts +228 -0
  131. package/src/repositories/obligation/index.ts +51 -0
  132. package/src/repositories/obligation/types.ts +71 -0
  133. package/src/repositories/obligation/utils.ts +57 -0
  134. package/src/repositories/poolAddresses/const.ts +5 -0
  135. package/src/repositories/poolAddresses/helpers.ts +422 -0
  136. package/src/repositories/poolAddresses/index.ts +56 -0
  137. package/src/repositories/poolAddresses/schema.ts +34 -0
  138. package/src/repositories/poolAddresses/types.ts +69 -0
  139. package/src/repositories/price/const.ts +1 -0
  140. package/src/repositories/price/helpers.ts +237 -0
  141. package/src/repositories/price/index.ts +91 -0
  142. package/src/repositories/price/schema.ts +24 -0
  143. package/src/repositories/price/types.ts +56 -0
  144. package/src/repositories/price/utils.ts +21 -0
  145. package/src/repositories/referral/bcs.ts +3 -0
  146. package/src/repositories/referral/helper.ts +24 -0
  147. package/src/repositories/referral/index.ts +31 -0
  148. package/src/repositories/referral/types.ts +33 -0
  149. package/src/repositories/spool/const.ts +1 -0
  150. package/src/repositories/spool/helpers.ts +471 -0
  151. package/src/repositories/spool/index.ts +135 -0
  152. package/src/{types/query/spool.ts → repositories/spool/types.ts} +67 -2
  153. package/src/repositories/spool/utils.ts +215 -0
  154. package/src/repositories/types.ts +39 -0
  155. package/src/repositories/utils.ts +137 -0
  156. package/src/repositories/veSca/bcs.ts +6 -0
  157. package/src/repositories/veSca/helpers.ts +341 -0
  158. package/src/repositories/veSca/index.ts +57 -0
  159. package/src/repositories/veSca/types.ts +79 -0
  160. package/src/repositories/veScaLoyaltyProgram/bcs.ts +3 -0
  161. package/src/repositories/veScaLoyaltyProgram/helpers.ts +135 -0
  162. package/src/repositories/veScaLoyaltyProgram/index.ts +28 -0
  163. package/src/repositories/veScaLoyaltyProgram/schema.ts +15 -0
  164. package/src/repositories/veScaLoyaltyProgram/types.ts +47 -0
  165. package/src/repositories/wiring/datasources.ts +42 -0
  166. package/src/repositories/wiring/metadata.ts +292 -0
  167. package/src/repositories/wiring/registry.ts +194 -0
  168. package/src/repositories/wiring/source.ts +63 -0
  169. package/src/repositories/xOracle/bcs.ts +7 -0
  170. package/src/repositories/xOracle/const.ts +1 -0
  171. package/src/repositories/xOracle/helpers.ts +304 -0
  172. package/src/repositories/xOracle/index.ts +45 -0
  173. package/src/repositories/xOracle/types.ts +96 -0
  174. package/src/repositories/xOracle/utils.ts +3 -0
  175. package/src/services/client/BorrowService.ts +229 -0
  176. package/src/services/client/CollateralService.ts +76 -0
  177. package/src/services/client/LendingService.ts +75 -0
  178. package/src/services/client/ReferralService.ts +71 -0
  179. package/src/services/client/SpoolService.ts +170 -0
  180. package/src/services/client/VeScaService.ts +142 -0
  181. package/src/services/client/types.ts +44 -0
  182. package/src/services/index.ts +8 -0
  183. package/src/services/query/portfolioCalculations.ts +1171 -0
  184. package/src/txBuilders/borrowIncentive/index.ts +80 -0
  185. package/src/txBuilders/borrowIncentive/moveCalls.ts +124 -0
  186. package/src/txBuilders/borrowIncentive/quick.ts +207 -0
  187. package/src/txBuilders/context.ts +62 -0
  188. package/src/txBuilders/core/index.ts +95 -0
  189. package/src/txBuilders/core/moveCalls.ts +241 -0
  190. package/src/txBuilders/core/quick.ts +306 -0
  191. package/src/{builders → txBuilders}/index.ts +35 -9
  192. package/src/txBuilders/loyaltyProgram/index.ts +78 -0
  193. package/src/txBuilders/loyaltyProgram/moveCalls.ts +44 -0
  194. package/src/txBuilders/loyaltyProgram/quick.ts +58 -0
  195. package/src/txBuilders/manifest.ts +160 -0
  196. package/src/txBuilders/modules.ts +70 -0
  197. package/src/{builders → txBuilders}/oracles/index.ts +3 -2
  198. package/src/{builders → txBuilders}/oracles/pyth.ts +4 -3
  199. package/src/txBuilders/referral/index.ts +72 -0
  200. package/src/txBuilders/referral/moveCalls.ts +93 -0
  201. package/src/txBuilders/referral/quick.ts +57 -0
  202. package/src/txBuilders/sCoin/index.ts +72 -0
  203. package/src/txBuilders/sCoin/moveCalls.ts +36 -0
  204. package/src/txBuilders/sCoin/quick.ts +34 -0
  205. package/src/txBuilders/spool/index.ts +82 -0
  206. package/src/txBuilders/spool/moveCalls.ts +79 -0
  207. package/src/{builders/spoolBuilder.ts → txBuilders/spool/quick.ts} +22 -162
  208. package/src/txBuilders/utils.ts +36 -0
  209. package/src/txBuilders/verify.ts +45 -0
  210. package/src/txBuilders/vesca/index.ts +75 -0
  211. package/src/txBuilders/vesca/moveCalls.ts +147 -0
  212. package/src/{builders/vescaBuilder.ts → txBuilders/vesca/quick.ts} +85 -274
  213. package/src/types/address.ts +4 -178
  214. package/src/types/builder/borrowIncentive.ts +4 -3
  215. package/src/types/builder/core.ts +6 -33
  216. package/src/types/builder/index.ts +5 -1
  217. package/src/types/builder/loyaltyProgram.ts +4 -3
  218. package/src/types/builder/modules.ts +49 -0
  219. package/src/types/builder/referral.ts +5 -4
  220. package/src/types/builder/sCoin.ts +20 -2
  221. package/src/types/builder/spool.ts +22 -2
  222. package/src/types/builder/vesca.ts +4 -12
  223. package/src/types/constant/index.ts +3 -1
  224. package/src/types/constant/queryKeys.ts +15 -8
  225. package/src/types/index.ts +5 -6
  226. package/src/types/internal/dto.ts +46 -0
  227. package/src/types/internal/index.ts +2 -0
  228. package/src/types/internal/move.ts +13 -0
  229. package/src/types/public/index.ts +21 -0
  230. package/src/types/query/core.ts +0 -317
  231. package/src/types/query/index.ts +3 -4
  232. package/src/types/query/portfolio.ts +2 -15
  233. package/src/types/repositories/borrowIncentive.ts +12 -0
  234. package/src/types/repositories/index.ts +9 -0
  235. package/src/types/repositories/loyaltyProgram.ts +2 -0
  236. package/src/types/repositories/market.ts +13 -0
  237. package/src/types/repositories/spool.ts +21 -0
  238. package/src/types/repositories/veSca.ts +5 -0
  239. package/src/types/repositories/veScaLoyaltyProgram.ts +2 -0
  240. package/src/types/sui.ts +0 -1
  241. package/src/utils/array.ts +7 -0
  242. package/src/utils/cache.ts +17 -0
  243. package/src/utils/object.ts +30 -12
  244. package/src/utils/query.ts +9 -190
  245. package/src/utils/vesca.ts +0 -8
  246. package/src/builders/borrowIncentiveBuilder.ts +0 -372
  247. package/src/builders/coreBuilder.ts +0 -636
  248. package/src/builders/loyaltyProgramBuilder.ts +0 -142
  249. package/src/builders/referralBuilder.ts +0 -192
  250. package/src/builders/sCoinBuilder.ts +0 -124
  251. package/src/index.ts +0 -13
  252. package/src/models/scallopAddress.ts +0 -841
  253. package/src/models/scallopAxios.ts +0 -185
  254. package/src/models/scallopConstants.ts +0 -380
  255. package/src/models/scallopIndexer.ts +0 -226
  256. package/src/models/scallopQuery.ts +0 -974
  257. package/src/models/scallopQueryClient.ts +0 -29
  258. package/src/models/scallopSuiKit.ts +0 -480
  259. package/src/models/scallopUtils.ts +0 -734
  260. package/src/queries/borrowIncentiveQuery.ts +0 -361
  261. package/src/queries/borrowLimitQuery.ts +0 -33
  262. package/src/queries/coreQuery.ts +0 -1173
  263. package/src/queries/flashloanFeeQuery.ts +0 -92
  264. package/src/queries/index.ts +0 -15
  265. package/src/queries/isolatedAssetQuery.ts +0 -103
  266. package/src/queries/loyaltyProgramQuery.ts +0 -178
  267. package/src/queries/ownerQuery.ts +0 -32
  268. package/src/queries/poolAddressesQuery.ts +0 -340
  269. package/src/queries/portfolioQuery.ts +0 -1149
  270. package/src/queries/priceQuery.ts +0 -37
  271. package/src/queries/referralQuery.ts +0 -42
  272. package/src/queries/sCoinQuery.ts +0 -195
  273. package/src/queries/spoolQuery.ts +0 -542
  274. package/src/queries/supplyLimitQuery.ts +0 -32
  275. package/src/queries/switchboardQuery.ts +0 -65
  276. package/src/queries/vescaQuery.ts +0 -312
  277. package/src/queries/xOracleQuery.ts +0 -149
  278. package/src/types/constant/common.ts +0 -55
  279. package/src/types/query/loyaltyProgram.ts +0 -12
  280. package/src/types/query/vesca.ts +0 -27
  281. package/src/utils/index.ts +0 -7
  282. package/src/utils/indexer.ts +0 -47
  283. /package/src/{models → datasources}/rateLimiter.ts +0 -0
@@ -0,0 +1,42 @@
1
+ import { ClientWithCoreApi } from '@mysten/sui/client';
2
+ import { API_BASE_URL, SDK_API_BASE_URL } from 'src/constants/api.js';
3
+ import { ApiDataSource } from 'src/datasources/api.js';
4
+ import { IndexerDataSource } from 'src/datasources/indexer.js';
5
+ import { OnChainDataSource } from 'src/datasources/onchain.js';
6
+
7
+ /**
8
+ * The on-chain datasource is the only repo datasource that needs to be instantiated with a client,
9
+ * since it needs to call on-chain methods that require a client. The indexer and API datasources
10
+ * are just thin wrappers around fetch, so they don't need a client and can be instantiated with
11
+ * just a URL (which defaults to the appropriate base URL if not provided).
12
+ */
13
+ export const createOnChainDataSource = (
14
+ client: ClientWithCoreApi,
15
+ url: string, // for cache keys
16
+ options?: { tokensPerSecond?: number }
17
+ ): OnChainDataSource =>
18
+ new OnChainDataSource({
19
+ // new-gen transport methods (getObjects/simulateTransaction/…) live on `.core`
20
+ client: client.core,
21
+ url,
22
+ // The datasource is now the single rate-limit point for every repo read
23
+ // (the old ScallopSuiKit query path is gone).
24
+ tokensPerSecond: options?.tokensPerSecond,
25
+ });
26
+
27
+ /**
28
+ * The indexer base URL defaults to `SDK_API_BASE_URL` inside `IndexerDataSource`.
29
+ * Pass `url` only to point at a non-default indexer.
30
+ */
31
+ export const createIndexerDataSource = (
32
+ url: string = SDK_API_BASE_URL
33
+ ): IndexerDataSource => new IndexerDataSource({ url });
34
+
35
+ /**
36
+ * Plain Scallop API datasource (defaults to `API_BASE_URL`, distinct from the
37
+ * indexer base). Injected into repos that read the public API rather than the
38
+ * indexer (e.g. `poolAddresses`). Pass `url` to override.
39
+ */
40
+ export const createApiDataSource = (
41
+ url: string = API_BASE_URL
42
+ ): ApiDataSource => new ApiDataSource({ url });
@@ -0,0 +1,292 @@
1
+ import type ScallopUtils from 'src/models/scallopUtils/index.js';
2
+ import type {
3
+ MarketRepoAddressConfig,
4
+ MarketRepoMetadata,
5
+ } from '../market/types.js';
6
+ import type { CoinBalanceMetadata } from '../coinBalance/types.js';
7
+ import type { FlashloanMetadata } from '../flashloan/types.js';
8
+ import type { ObligationRepoMetadata } from '../obligation/types.js';
9
+ import type { BorrowIncentiveMetadata } from '../borrowIncentive/types.js';
10
+ import type { ReferralRepoMetadata } from '../referral/types.js';
11
+ import type { PriceRepositoryMetadata } from '../price/types.js';
12
+ import type { PoolAddressesRepoMetadata } from '../poolAddresses/types.js';
13
+ import type { IsolatedAssetsMetadata } from '../isolatedAssets/types.js';
14
+ import type { VeScaRepoMetadata } from '../veSca/types.js';
15
+ import type { LoyaltyProgramRepoMetadata } from '../loyaltyProgram/types.js';
16
+ import type { VeScaLoyaltyProgramRepoMetadata } from '../veScaLoyaltyProgram/types.js';
17
+ import type { XOracleMetadata } from '../xOracle/types.js';
18
+ import type { SpoolMetadata } from '../spool/types.js';
19
+ import { SUPPORTED_ORACLES } from '../xOracle/const.js';
20
+ import { ScallopConfigError } from 'src/errors/index.js';
21
+
22
+ /**
23
+ * The ONE seam between the SDK models (`ScallopUtils` / `ScallopConstants`) and
24
+ * the pure repositories layer. Each `buildXMetadata` is a pure function that
25
+ * projects the model surface into the plain data + bound helper functions a repo
26
+ * expects. Repos never import the models — everything they need flows through here.
27
+ *
28
+ * Helpers are arrow-wrapped (not passed by reference) so they keep ScallopUtils'
29
+ * `this` binding. Address ids come from `utils.address.get(path)` — paths mirror
30
+ * the ones the old query layer used.
31
+ */
32
+
33
+ export const buildMarketMetadata = (
34
+ utils: ScallopUtils
35
+ ): MarketRepoMetadata => ({
36
+ whitelist: {
37
+ lending: utils.constants.whitelist.lending,
38
+ collateral: utils.constants.whitelist.collateral,
39
+ },
40
+ poolAddresses: utils.constants.poolAddresses,
41
+ parseCoinNameFromType: (coinType) => utils.parseCoinNameFromType(coinType),
42
+ parseCoinType: (coinName) => utils.parseCoinType(coinName),
43
+ parseSymbol: (coinName) => utils.parseSymbol(coinName),
44
+ parseMarketCoinType: (coinName) => utils.parseMarketCoinType(coinName),
45
+ parseMarketCoinName: (coinName) => utils.parseMarketCoinName(coinName),
46
+ parseSCoinType: (sCoinName) => utils.parseSCoinType(sCoinName),
47
+ getCoinWrappedType: (coinName) => utils.getCoinWrappedType(coinName),
48
+ getCoinDecimal: (coinName) => utils.getCoinDecimal(coinName),
49
+ parseAprToApy: (apr) => utils.parseAprToApy(apr),
50
+ });
51
+
52
+ export const buildMarketAddresses = (
53
+ utils: ScallopUtils
54
+ ): MarketRepoAddressConfig => ({
55
+ queryPackageId: utils.address.get('core.packages.query.id'),
56
+ market: utils.address.get('core.market'),
57
+ });
58
+
59
+ export const buildCoinBalanceMetadata = (
60
+ utils: ScallopUtils
61
+ ): CoinBalanceMetadata => {
62
+ const addresses = utils.address.getAddresses();
63
+ if (!addresses) {
64
+ throw new ScallopConfigError(
65
+ 'Addresses are not initialized; call init() before building repositories'
66
+ );
67
+ }
68
+ return {
69
+ whitelist: {
70
+ lending: utils.constants.whitelist.lending,
71
+ scoin: utils.constants.whitelist.scoin,
72
+ },
73
+ addresses: {
74
+ scoin: addresses.scoin,
75
+ },
76
+ parseCoinType: (coinName) => utils.parseCoinType(coinName),
77
+ parseSCoinType: (sCoinName) => utils.parseSCoinType(sCoinName),
78
+ parseMarketCoinType: (coinName) => utils.parseMarketCoinType(coinName),
79
+ parseSCoinNameFromType: (sCoinType) =>
80
+ utils.parseSCoinNameFromType(sCoinType),
81
+ parseUnderlyingSCoinType: (sCoinName) =>
82
+ utils.parseUnderlyingSCoinType(sCoinName),
83
+ getSCoinTreasury: (sCoinName) => utils.getSCoinTreasury(sCoinName),
84
+ getCoinDecimal: (coinName) => utils.getCoinDecimal(coinName),
85
+ parseCoinName: (marketCoinName) => utils.parseCoinName(marketCoinName),
86
+ };
87
+ };
88
+
89
+ export const buildFlashloanMetadata = (
90
+ utils: ScallopUtils
91
+ ): FlashloanMetadata => {
92
+ const entries = Object.entries(utils.constants.coinTypeToCoinNameMap).filter(
93
+ (entry): entry is [string, string] => entry[1] !== undefined
94
+ );
95
+ return { coinTypeToCoinNameMap: new Map(entries) };
96
+ };
97
+
98
+ export const buildObligationMetadata = (
99
+ utils: ScallopUtils
100
+ ): ObligationRepoMetadata => ({
101
+ addresses: {
102
+ protocolObjectId: utils.address.get('core.object'),
103
+ queryPackageId: utils.address.get('core.packages.query.id'),
104
+ version: utils.address.get('core.version'),
105
+ market: utils.address.get('core.market'),
106
+ },
107
+ });
108
+
109
+ export const buildBorrowIncentiveMetadata = (
110
+ utils: ScallopUtils
111
+ ): BorrowIncentiveMetadata => {
112
+ const addresses = utils.address.getAddresses();
113
+ if (!addresses) {
114
+ throw new ScallopConfigError(
115
+ 'Addresses are not initialized; call init() before building repositories'
116
+ );
117
+ }
118
+ return {
119
+ whitelist: { lending: utils.constants.whitelist.lending },
120
+ addresses: {
121
+ borrowIncentive: addresses.borrowIncentive,
122
+ core: { object: utils.address.get('core.object') },
123
+ vesca: { object: utils.address.get('vesca.object') },
124
+ },
125
+ parseCoinNameFromType: (coinType) => utils.parseCoinNameFromType(coinType),
126
+ parseSymbol: (coinName) => utils.parseSymbol(coinName),
127
+ getCoinDecimal: (coinName) => utils.getCoinDecimal(coinName),
128
+ };
129
+ };
130
+
131
+ export const buildReferralMetadata = (
132
+ utils: ScallopUtils
133
+ ): ReferralRepoMetadata => ({
134
+ addresses: {
135
+ referral: {
136
+ bindingTableId: utils.address.get('referral.bindingTableId'),
137
+ },
138
+ },
139
+ });
140
+
141
+ export const buildPriceMetadata = (
142
+ utils: ScallopUtils
143
+ ): PriceRepositoryMetadata => {
144
+ const addresses = utils.address.getAddresses();
145
+ if (!addresses) {
146
+ throw new ScallopConfigError(
147
+ 'Addresses are not initialized; call init() before building repositories'
148
+ );
149
+ }
150
+ // Keep only present coins (drop undefined entries) to satisfy the repo's
151
+ // dense `core.coins` contract.
152
+ const coins = Object.fromEntries(
153
+ Object.entries(addresses.core.coins).filter(
154
+ (entry): entry is [string, NonNullable<(typeof entry)[1]>] =>
155
+ entry[1] !== undefined
156
+ )
157
+ );
158
+ return { addresses: { coins } };
159
+ };
160
+
161
+ export const buildPoolAddressesMetadata = (
162
+ utils: ScallopUtils
163
+ ): PoolAddressesRepoMetadata => {
164
+ const addresses = utils.address.getAddresses();
165
+ if (!addresses) {
166
+ throw new ScallopConfigError(
167
+ 'Addresses are not initialized; call init() before building repositories'
168
+ );
169
+ }
170
+ return {
171
+ addresses: {
172
+ core: { coins: addresses.core.coins, market: addresses.core.market },
173
+ spool: { pools: addresses.spool.pools },
174
+ scoin: { coins: addresses.scoin.coins },
175
+ },
176
+ };
177
+ };
178
+
179
+ export const buildIsolatedAssetsMetadata = (
180
+ utils: ScallopUtils
181
+ ): IsolatedAssetsMetadata => ({
182
+ addresses: { market: utils.address.get('core.market') },
183
+ poolAddresses: utils.constants.poolAddresses,
184
+ whitelist: { lending: utils.constants.whitelist.lending },
185
+ });
186
+
187
+ export const buildVeScaMetadata = (utils: ScallopUtils): VeScaRepoMetadata => ({
188
+ addresses: {
189
+ veSca: {
190
+ id: utils.address.get('vesca.id'),
191
+ config: utils.address.get('vesca.config'),
192
+ tableId: utils.address.get('vesca.tableId'),
193
+ object: utils.address.get('vesca.object'),
194
+ treasury: utils.address.get('vesca.treasury'),
195
+ },
196
+ },
197
+ });
198
+
199
+ export const buildLoyaltyProgramMetadata = (
200
+ utils: ScallopUtils
201
+ ): LoyaltyProgramRepoMetadata => ({
202
+ addresses: {
203
+ loyaltyProgram: {
204
+ rewardPool: utils.address.get('loyaltyProgram.rewardPool'),
205
+ },
206
+ },
207
+ });
208
+
209
+ export const buildVeScaLoyaltyProgramMetadata = (
210
+ utils: ScallopUtils
211
+ ): VeScaLoyaltyProgramRepoMetadata => {
212
+ const addresses = utils.address.getAddresses();
213
+ if (!addresses) {
214
+ throw new ScallopConfigError(
215
+ 'Addresses are not initialized; call init() before building repositories'
216
+ );
217
+ }
218
+ return {
219
+ addresses: {
220
+ veSca: { tableId: addresses.vesca.tableId },
221
+ veScaLoyaltyProgram: {
222
+ veScaRewardPool: addresses.veScaLoyaltyProgram.veScaRewardPool,
223
+ veScaRewardTableId: addresses.veScaLoyaltyProgram.veScaRewardTableId,
224
+ },
225
+ },
226
+ };
227
+ };
228
+
229
+ export const buildSpoolMetadata = (utils: ScallopUtils): SpoolMetadata => ({
230
+ whitelist: { spool: utils.constants.whitelist.spool },
231
+ addresses: {
232
+ spoolObjectId: utils.address.get('spool.object'),
233
+ // dense map over the spool whitelist (market-coin names) → pool object ids
234
+ spools: [...utils.constants.whitelist.spool].reduce(
235
+ (acc, name) => {
236
+ acc[name] = {
237
+ id: utils.address.get(`spool.pools.${name}.id`),
238
+ rewardPoolId: utils.address.get(`spool.pools.${name}.rewardPoolId`),
239
+ };
240
+ return acc;
241
+ },
242
+ {} as Record<string, { id: string; rewardPoolId: string }>
243
+ ),
244
+ },
245
+ poolAddresses: utils.constants.poolAddresses,
246
+ parseCoinName: (marketCoinName) => utils.parseCoinName(marketCoinName),
247
+ parseSymbol: (coinName) => utils.parseSymbol(coinName),
248
+ parseCoinType: (coinName) => utils.parseCoinType(coinName),
249
+ parseMarketCoinType: (coinName) => utils.parseMarketCoinType(coinName),
250
+ parseSCoinType: (sCoinName) => utils.parseSCoinType(sCoinName),
251
+ isMarketCoin: (coinName) => utils.isMarketCoin(coinName),
252
+ getCoinDecimal: (coinName) => utils.getCoinDecimal(coinName) ?? 0,
253
+ getSpoolRewardCoinName: () => utils.getSpoolRewardCoinName(),
254
+ });
255
+
256
+ export const buildXOracleMetadata = (utils: ScallopUtils): XOracleMetadata => ({
257
+ addresses: {
258
+ // per-oracle package object ids (projection from core.packages.<oracle>.object)
259
+ ...SUPPORTED_ORACLES.reduce(
260
+ (acc, oracle) => {
261
+ acc[oracle] = {
262
+ object: utils.address.get(`core.packages.${oracle}.object`),
263
+ };
264
+ return acc;
265
+ },
266
+ {} as Record<(typeof SUPPORTED_ORACLES)[number], { object: string }>
267
+ ),
268
+ xOracleObject: utils.address.get('core.packages.xOracle.object'),
269
+ oracles: {
270
+ primaryPriceUpdatePolicyVecsetId: utils.address.get(
271
+ 'core.oracles.primaryPriceUpdatePolicyVecsetId'
272
+ ),
273
+ secondaryPriceUpdatePolicyVecsetId: utils.address.get(
274
+ 'core.oracles.secondaryPriceUpdatePolicyVecsetId'
275
+ ),
276
+ primaryPriceUpdatePolicyObject: utils.address.get(
277
+ 'core.oracles.primaryPriceUpdatePolicyObject'
278
+ ),
279
+ secondaryPriceUpdatePolicyObject: utils.address.get(
280
+ 'core.oracles.secondaryPriceUpdatePolicyObject'
281
+ ),
282
+ switchboardRegistryTableId: utils.address.get(
283
+ 'core.oracles.switchboard.registryTableId'
284
+ ),
285
+ },
286
+ },
287
+ whitelist: { lending: utils.constants.whitelist.lending },
288
+ parseCoinNameFromType: (type) => utils.parseCoinNameFromType(type),
289
+ parseCoinType: (coinName) => utils.parseCoinType(coinName),
290
+ getSwitchboardAggAddress: (coinName) =>
291
+ utils.address.get(`core.coins.${coinName}.oracle.switchboard`),
292
+ });
@@ -0,0 +1,194 @@
1
+ import type ScallopUtils from 'src/models/scallopUtils/index.js';
2
+ import { QueryClient, QueryClientConfig } from '@tanstack/query-core';
3
+ import type { Logger } from 'src/logger/index.js';
4
+ import { createApiDataSource, createIndexerDataSource } from './datasources.js';
5
+ import {
6
+ buildBorrowIncentiveMetadata,
7
+ buildReferralMetadata,
8
+ buildPriceMetadata,
9
+ buildPoolAddressesMetadata,
10
+ buildCoinBalanceMetadata,
11
+ buildFlashloanMetadata,
12
+ buildIsolatedAssetsMetadata,
13
+ buildLoyaltyProgramMetadata,
14
+ buildMarketAddresses,
15
+ buildMarketMetadata,
16
+ buildObligationMetadata,
17
+ buildSpoolMetadata,
18
+ buildVeScaLoyaltyProgramMetadata,
19
+ buildVeScaMetadata,
20
+ buildXOracleMetadata,
21
+ } from './metadata.js';
22
+ import { MarketRepository } from '../market/index.js';
23
+ import { CoinBalanceRepository } from '../coinBalance/index.js';
24
+ import { FlashloanRepository } from '../flashloan/index.js';
25
+ import { ObligationRepository } from '../obligation/index.js';
26
+ import { BorrowIncentiveRepository } from '../borrowIncentive/index.js';
27
+ import { IsolatedAssetsRepository } from '../isolatedAssets/index.js';
28
+ import { VeScaRepository } from '../veSca/index.js';
29
+ import { LoyaltyProgramRepository } from '../loyaltyProgram/index.js';
30
+ import { XOracleRepository } from '../xOracle/index.js';
31
+ import { SpoolRepository } from '../spool/index.js';
32
+ import { VeScaLoyaltyProgramRepository } from '../veScaLoyaltyProgram/index.js';
33
+ import { ReferralRepository } from '../referral/index.js';
34
+ import { PoolAddressesRepository } from '../poolAddresses/index.js';
35
+ import { PriceRepository } from '../price/index.js';
36
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache.js';
37
+
38
+ /**
39
+ * Inputs the registry needs. `ScallopUtils` is the single hub — it exposes
40
+ * `onchain`, `queryClient`, `logger`, `address`, and `constants`, so the
41
+ * registry can derive every datasource + metadata bundle
42
+ * from it.
43
+ */
44
+ export type RepositoryDeps = {
45
+ utils: ScallopUtils;
46
+ queryClient?: QueryClient; // Optional override for the utils query client
47
+ queryClientConfig?: QueryClientConfig; // Optional override for the utils query client config
48
+ /** Override the indexer base URL; defaults to the Scallop indexer. */
49
+ indexerUrl?: string;
50
+ };
51
+
52
+ /**
53
+ * The set of wired domain repositories. Every domain below is wired into the
54
+ * facade — `ScallopQuery` delegates each read to `repos.<domain>`.
55
+ */
56
+ export interface Repositories {
57
+ readonly market: MarketRepository;
58
+ readonly coinBalance: CoinBalanceRepository;
59
+ readonly flashloan: FlashloanRepository;
60
+ readonly obligation: ObligationRepository;
61
+ readonly borrowIncentive: BorrowIncentiveRepository;
62
+ readonly isolatedAssets: IsolatedAssetsRepository;
63
+ readonly veSca: VeScaRepository;
64
+ readonly loyaltyProgram: LoyaltyProgramRepository;
65
+ readonly xOracle: XOracleRepository;
66
+ readonly spool: SpoolRepository;
67
+ readonly veScaLoyaltyProgram: VeScaLoyaltyProgramRepository;
68
+ readonly referral: ReferralRepository;
69
+ readonly price: PriceRepository;
70
+ readonly poolAddresses: PoolAddressesRepository;
71
+ }
72
+
73
+ /**
74
+ * Build the repository registry from the SDK models. Repos are constructed
75
+ * lazily (on first access) and memoised, so unused domains cost nothing and
76
+ * metadata is built at most once per domain.
77
+ */
78
+ export const createRepositories = (deps: RepositoryDeps): Repositories => {
79
+ const { utils, indexerUrl, queryClientConfig = DEFAULT_CACHE_OPTIONS } = deps;
80
+
81
+ const onchain = utils.onchain;
82
+ const indexer = createIndexerDataSource(indexerUrl);
83
+ const queryClient: QueryClient =
84
+ deps.queryClient ?? new QueryClient(queryClientConfig);
85
+ const logger: Logger = utils.logger;
86
+ const base = { onchain, queryClient, logger };
87
+
88
+ let market: MarketRepository | undefined;
89
+ let coinBalance: CoinBalanceRepository | undefined;
90
+ let flashloan: FlashloanRepository | undefined;
91
+ let obligation: ObligationRepository | undefined;
92
+ let borrowIncentive: BorrowIncentiveRepository | undefined;
93
+ let isolatedAssets: IsolatedAssetsRepository | undefined;
94
+ let veSca: VeScaRepository | undefined;
95
+ let loyaltyProgram: LoyaltyProgramRepository | undefined;
96
+ let xOracle: XOracleRepository | undefined;
97
+ let spool: SpoolRepository | undefined;
98
+ let veScaLoyaltyProgram: VeScaLoyaltyProgramRepository | undefined;
99
+ let referral: ReferralRepository | undefined;
100
+ let price: PriceRepository | undefined;
101
+ let poolAddresses: PoolAddressesRepository | undefined;
102
+
103
+ return {
104
+ get market() {
105
+ return (market ??= new MarketRepository({
106
+ ...base,
107
+ indexer,
108
+ addresses: buildMarketAddresses(utils),
109
+ metadata: buildMarketMetadata(utils),
110
+ }));
111
+ },
112
+ get coinBalance() {
113
+ return (coinBalance ??= new CoinBalanceRepository({
114
+ ...base,
115
+ metadata: buildCoinBalanceMetadata(utils),
116
+ }));
117
+ },
118
+ get flashloan() {
119
+ return (flashloan ??= new FlashloanRepository({
120
+ ...base,
121
+ metadata: buildFlashloanMetadata(utils),
122
+ }));
123
+ },
124
+ get obligation() {
125
+ return (obligation ??= new ObligationRepository({
126
+ ...base,
127
+ metadata: buildObligationMetadata(utils),
128
+ }));
129
+ },
130
+ get borrowIncentive() {
131
+ return (borrowIncentive ??= new BorrowIncentiveRepository({
132
+ ...base,
133
+ metadata: buildBorrowIncentiveMetadata(utils),
134
+ }));
135
+ },
136
+ get isolatedAssets() {
137
+ return (isolatedAssets ??= new IsolatedAssetsRepository({
138
+ ...base,
139
+ metadata: buildIsolatedAssetsMetadata(utils),
140
+ }));
141
+ },
142
+ get veSca() {
143
+ return (veSca ??= new VeScaRepository({
144
+ ...base,
145
+ metadata: buildVeScaMetadata(utils),
146
+ }));
147
+ },
148
+ get loyaltyProgram() {
149
+ return (loyaltyProgram ??= new LoyaltyProgramRepository({
150
+ ...base,
151
+ metadata: buildLoyaltyProgramMetadata(utils),
152
+ }));
153
+ },
154
+ get xOracle() {
155
+ return (xOracle ??= new XOracleRepository({
156
+ ...base,
157
+ metadata: buildXOracleMetadata(utils),
158
+ }));
159
+ },
160
+ get spool() {
161
+ return (spool ??= new SpoolRepository({
162
+ ...base,
163
+ indexer,
164
+ metadata: buildSpoolMetadata(utils),
165
+ }));
166
+ },
167
+ get veScaLoyaltyProgram() {
168
+ return (veScaLoyaltyProgram ??= new VeScaLoyaltyProgramRepository({
169
+ ...base,
170
+ metadata: buildVeScaLoyaltyProgramMetadata(utils),
171
+ }));
172
+ },
173
+ get referral() {
174
+ return (referral ??= new ReferralRepository({
175
+ ...base,
176
+ metadata: buildReferralMetadata(utils),
177
+ }));
178
+ },
179
+ get price() {
180
+ return (price ??= new PriceRepository({
181
+ ...base,
182
+ indexer,
183
+ metadata: buildPriceMetadata(utils),
184
+ }));
185
+ },
186
+ get poolAddresses() {
187
+ return (poolAddresses ??= new PoolAddressesRepository({
188
+ ...base,
189
+ api: createApiDataSource(),
190
+ metadata: buildPoolAddressesMetadata(utils),
191
+ }));
192
+ },
193
+ };
194
+ };
@@ -0,0 +1,63 @@
1
+ import type { QuerySource } from '../utils.js';
2
+
3
+ /**
4
+ * The legacy facade-level data-source flags. These remain the public arg shape
5
+ * that backwards-compatible `ScallopQuery` read methods accept; `fromQueryOptions`
6
+ * maps them onto the repositories' `QuerySource`. (The values are the pre-v4
7
+ * vocabulary — `'rpc' | 'indexer' | 'indexer-first'` — deliberately distinct from
8
+ * the repos `QuerySource`.)
9
+ */
10
+ export type LegacyQuerySource = 'rpc' | 'indexer' | 'indexer-first';
11
+
12
+ export type QueryOptions = {
13
+ source?: LegacyQuerySource;
14
+ indexer?: boolean;
15
+ };
16
+
17
+ /**
18
+ * Legacy ScallopQuery read methods expressed data-source choice three different
19
+ * ways: a `QueryOptions.source`, an `indexer: boolean`, or a
20
+ * `useOnChainQuery: boolean`. The repositories layer speaks a single
21
+ * `QuerySource`. `toQuerySource` is the one adapter that normalises the old
22
+ * flags so the facade can stay backwards-compatible while delegating to repos.
23
+ *
24
+ * Precedence: an explicit `source` wins; then `useOnChainQuery`; then `indexer`;
25
+ * otherwise default to `'api-first'` (indexer with onchain fallback) for
26
+ * dual-source domains.
27
+ */
28
+ export type SourceFlags = {
29
+ source?: QuerySource;
30
+ indexer?: boolean;
31
+ useOnChainQuery?: boolean;
32
+ };
33
+
34
+ export const toQuerySource = (flags: SourceFlags = {}): QuerySource => {
35
+ if (flags.source) return flags.source;
36
+ if (flags.useOnChainQuery !== undefined) {
37
+ return flags.useOnChainQuery ? 'onchain' : 'api-first';
38
+ }
39
+ if (flags.indexer !== undefined) {
40
+ return flags.indexer ? 'api-first' : 'onchain';
41
+ }
42
+ return 'api-first';
43
+ };
44
+
45
+ const LEGACY_SOURCE: Record<
46
+ NonNullable<QueryOptions['source']>,
47
+ QuerySource
48
+ > = {
49
+ rpc: 'onchain',
50
+ indexer: 'api',
51
+ 'indexer-first': 'api-first',
52
+ };
53
+
54
+ /**
55
+ * Map a legacy `QueryOptions` ({ source?: 'rpc' | 'indexer' | 'indexer-first',
56
+ * indexer? }) to the repos' `QuerySource`. Mirrors the old `resolveQuerySource`:
57
+ * an explicit legacy `source` wins; else `indexer` → 'api-first', otherwise
58
+ * 'onchain' (the old default was 'rpc').
59
+ */
60
+ export const fromQueryOptions = (options?: QueryOptions): QuerySource => {
61
+ if (options?.source) return LEGACY_SOURCE[options.source];
62
+ return options?.indexer ? 'api-first' : 'onchain';
63
+ };
@@ -0,0 +1,7 @@
1
+ import { bcs, BcsType } from '@mysten/sui/bcs';
2
+
3
+ const PriceRuleTypeName = bcs.struct('TypeName', { name: bcs.string() });
4
+ const VecSet = (T: BcsType<{ name: string }>) =>
5
+ bcs.struct('VecSet', { contents: bcs.vector(T) });
6
+
7
+ export const PricePolicyRulesVecSet = VecSet(PriceRuleTypeName);
@@ -0,0 +1 @@
1
+ export const SUPPORTED_ORACLES = ['supra', 'switchboard', 'pyth'] as const;