@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,34 @@
1
+ import { GenerateSCoinQuickMethod } from 'src/types/index.js';
2
+ import { requireSender } from 'src/utils/builder.js';
3
+
4
+ export const generateSCoinQuickMethod: GenerateSCoinQuickMethod = ({
5
+ ctx,
6
+ txBlock,
7
+ }) => {
8
+ return {
9
+ mintSCoinQuick: async (marketCoinName, amount) => {
10
+ const sender = requireSender(txBlock);
11
+ const { leftCoin, takeCoin } = await ctx.coins.selectMarketCoin(
12
+ txBlock,
13
+ marketCoinName,
14
+ amount,
15
+ sender
16
+ );
17
+
18
+ txBlock.transferObjects([leftCoin], sender);
19
+ return txBlock.mintSCoin(marketCoinName, takeCoin);
20
+ },
21
+ burnSCoinQuick: async (sCoinName, amount) => {
22
+ const sender = requireSender(txBlock);
23
+ const { leftCoin, takeCoin } = await ctx.coins.selectSCoin(
24
+ txBlock,
25
+ sCoinName,
26
+ amount,
27
+ sender
28
+ );
29
+
30
+ txBlock.transferObjects([leftCoin], sender);
31
+ return txBlock.burnSCoin(sCoinName, takeCoin);
32
+ },
33
+ };
34
+ };
@@ -0,0 +1,82 @@
1
+ import { Transaction } from '@mysten/sui/transactions';
2
+ import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
3
+ import { generateSpoolNormalMethod } from './moveCalls.js';
4
+ import { generateSpoolQuickMethod } from './quick.js';
5
+ import type { ScallopBuilder } from 'src/models/index.js';
6
+ import type {
7
+ SuiTxBlockWithSpoolNormalMethods,
8
+ SpoolTxBlock,
9
+ ScallopTxBlock,
10
+ SuiTxBlockWithSCoin,
11
+ SpoolActionContext,
12
+ } from 'src/types/index.js';
13
+ import type { MoveCallContext } from '../context.js';
14
+
15
+ /**
16
+ * Create an enhanced transaction block instance for interaction with spool modules of the Scallop contract.
17
+ *
18
+ * @param builder - Scallop builder instance.
19
+ * @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
20
+ * @return Scallop spool txBlock.
21
+ */
22
+ export const newSpoolTxBlock = (
23
+ builder: ScallopBuilder,
24
+ initTxBlock?:
25
+ | ScallopTxBlock
26
+ | SuiKitTxBlock
27
+ | Transaction
28
+ | SuiTxBlockWithSCoin
29
+ ) => {
30
+ const txBlock =
31
+ initTxBlock instanceof Transaction
32
+ ? new SuiKitTxBlock(initTxBlock)
33
+ : initTxBlock
34
+ ? initTxBlock
35
+ : new SuiKitTxBlock();
36
+
37
+ // Build the narrow contexts once from `builder`, binding the closures.
38
+ const moveCallContext: MoveCallContext = {
39
+ address: builder.address,
40
+ moveCall: builder.moveCall.bind(builder),
41
+ utils: builder.utils,
42
+ };
43
+
44
+ const actionContext: SpoolActionContext = {
45
+ reads: {
46
+ getAllStakeAccounts: (ownerAddress) =>
47
+ builder.query.getAllStakeAccounts(ownerAddress),
48
+ },
49
+ coins: {
50
+ selectMarketCoin: (...args) => builder.selectMarketCoin(...args),
51
+ selectSCoin: (...args) => builder.selectSCoin(...args),
52
+ },
53
+ };
54
+
55
+ const normalMethod = generateSpoolNormalMethod({
56
+ ctx: moveCallContext,
57
+ txBlock,
58
+ });
59
+
60
+ const normalTxBlock = new Proxy(txBlock, {
61
+ get: (target, prop) => {
62
+ if (prop in normalMethod) {
63
+ return Reflect.get(normalMethod, prop);
64
+ }
65
+ return Reflect.get(target, prop);
66
+ },
67
+ }) as SuiTxBlockWithSpoolNormalMethods;
68
+
69
+ const quickMethod = generateSpoolQuickMethod({
70
+ ctx: actionContext,
71
+ txBlock: normalTxBlock,
72
+ });
73
+
74
+ return new Proxy(normalTxBlock, {
75
+ get: (target, prop) => {
76
+ if (prop in quickMethod) {
77
+ return Reflect.get(quickMethod, prop);
78
+ }
79
+ return Reflect.get(target, prop);
80
+ },
81
+ }) as SpoolTxBlock;
82
+ };
@@ -0,0 +1,79 @@
1
+ import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';
2
+ import type { SpoolIds, GenerateSpoolNormalMethod } from 'src/types/index.js';
3
+
4
+ /**
5
+ * Generate spool normal methods.
6
+ *
7
+ * @param ctx - Pure Move-call context (address reads, coin-type parsing, moveCall).
8
+ * @param txBlock - TxBlock created by SuiKit .
9
+ * @return Spool normal methods.
10
+ */
11
+ export const generateSpoolNormalMethod: GenerateSpoolNormalMethod = ({
12
+ ctx,
13
+ txBlock,
14
+ }) => {
15
+ const spoolIds: SpoolIds = {
16
+ spoolPkg: ctx.address.get('spool.id'),
17
+ };
18
+ const clockObjectRef = txBlock.sharedObjectRef({
19
+ objectId: SUI_CLOCK_OBJECT_ID,
20
+ mutable: false,
21
+ initialSharedVersion: '1',
22
+ });
23
+
24
+ return {
25
+ createStakeAccount: (stakeMarketCoinName) => {
26
+ const marketCoinType = ctx.utils.parseMarketCoinType(stakeMarketCoinName);
27
+ const stakePoolId = ctx.address.get(
28
+ `spool.pools.${stakeMarketCoinName}.id`
29
+ );
30
+ return ctx.moveCall(
31
+ txBlock,
32
+ `${spoolIds.spoolPkg}::user::new_spool_account`,
33
+ [stakePoolId, clockObjectRef],
34
+ [marketCoinType]
35
+ );
36
+ },
37
+ stake: (stakeAccount, coin, stakeMarketCoinName) => {
38
+ const marketCoinType = ctx.utils.parseMarketCoinType(stakeMarketCoinName);
39
+ const stakePoolId = ctx.address.get(
40
+ `spool.pools.${stakeMarketCoinName}.id`
41
+ );
42
+ ctx.moveCall(
43
+ txBlock,
44
+ `${spoolIds.spoolPkg}::user::stake`,
45
+ [stakePoolId, stakeAccount, coin, clockObjectRef],
46
+ [marketCoinType]
47
+ );
48
+ },
49
+ unstake: (stakeAccount, amount, stakeMarketCoinName) => {
50
+ const marketCoinType = ctx.utils.parseMarketCoinType(stakeMarketCoinName);
51
+ const stakePoolId = ctx.address.get(
52
+ `spool.pools.${stakeMarketCoinName}.id`
53
+ );
54
+ return ctx.moveCall(
55
+ txBlock,
56
+ `${spoolIds.spoolPkg}::user::unstake`,
57
+ [stakePoolId, stakeAccount, amount, clockObjectRef],
58
+ [marketCoinType]
59
+ );
60
+ },
61
+ claim: (stakeAccount, stakeMarketCoinName) => {
62
+ const stakePoolId = ctx.address.get(
63
+ `spool.pools.${stakeMarketCoinName}.id`
64
+ ) as string;
65
+ const rewardPoolId = ctx.address.get(
66
+ `spool.pools.${stakeMarketCoinName}.rewardPoolId`
67
+ ) as string;
68
+ const marketCoinType = ctx.utils.parseMarketCoinType(stakeMarketCoinName);
69
+ const rewardCoinName = ctx.utils.getSpoolRewardCoinName();
70
+ const rewardCoinType = ctx.utils.parseCoinType(rewardCoinName);
71
+ return ctx.moveCall(
72
+ txBlock,
73
+ `${spoolIds.spoolPkg}::user::redeem_rewards`,
74
+ [stakePoolId, rewardPoolId, stakeAccount, clockObjectRef],
75
+ [marketCoinType, rewardCoinType]
76
+ );
77
+ },
78
+ };
79
+ };
@@ -1,19 +1,11 @@
1
- import { Transaction } from '@mysten/sui/transactions';
2
- import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';
3
- import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
4
- import { getStakeAccounts } from '../queries/spoolQuery.js';
5
- import { requireSender } from '../utils/index.js';
1
+ import { requireSender } from '../../utils/builder.js';
2
+ import type { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
6
3
  import type { SuiAddressArg } from '@scallop-io/sui-kit';
7
4
  import type { TransactionResult } from '@mysten/sui/transactions';
8
- import type { ScallopBuilder } from 'src/models/index.js';
9
5
  import type {
10
- SpoolIds,
11
- GenerateSpoolNormalMethod,
12
6
  GenerateSpoolQuickMethod,
7
+ SpoolActionContext,
13
8
  SuiTxBlockWithSpoolNormalMethods,
14
- SpoolTxBlock,
15
- ScallopTxBlock,
16
- SuiTxBlockWithSCoin,
17
9
  } from 'src/types/index.js';
18
10
 
19
11
  /**
@@ -23,7 +15,7 @@ import type {
23
15
  * If the stake account id is provided, directly return it.
24
16
  * Otherwise, automatically get all stake account id from the sender.
25
17
  *
26
- * @param builder - Scallop builder instance.
18
+ * @param ctx - Spool action context (provides `reads.getAllStakeAccounts`).
27
19
  * @param txBlock - TxBlock created by SuiKit.
28
20
  * @param stakeMarketCoinName - The name of the market coin supported for staking.
29
21
  * @param stakeAccountId - Stake account id.
@@ -31,16 +23,16 @@ import type {
31
23
  */
32
24
  const requireStakeAccountIds = async (
33
25
  ...params: [
34
- builder: ScallopBuilder,
26
+ ctx: SpoolActionContext,
35
27
  txBlock: SuiKitTxBlock,
36
28
  stakeMarketCoinName: string,
37
29
  stakeAccountId?: SuiAddressArg,
38
30
  ]
39
31
  ) => {
40
- const [builder, txBlock, stakeMarketCoinName, stakeAccountId] = params;
32
+ const [ctx, txBlock, stakeMarketCoinName, stakeAccountId] = params;
41
33
  if (params.length === 4 && stakeAccountId) return [stakeAccountId];
42
34
  const sender = requireSender(txBlock);
43
- const stakeAccounts = await getStakeAccounts(builder, sender);
35
+ const stakeAccounts = await ctx.reads.getAllStakeAccounts(sender);
44
36
  if (stakeAccounts[stakeMarketCoinName].length === 0) {
45
37
  throw new Error(`No stake account id found for sender ${sender}`);
46
38
  }
@@ -54,7 +46,7 @@ const requireStakeAccountIds = async (
54
46
  * If the stake account id is provided, directly return its account.
55
47
  * Otherwise, automatically get all stake account from the sender.
56
48
  *
57
- * @param builder - Scallop builder instance.
49
+ * @param ctx - Spool action context (provides `reads.getAllStakeAccounts`).
58
50
  * @param txBlock - TxBlock created by SuiKit.
59
51
  * @param stakeMarketCoinName - The name of the market coin supported for staking.
60
52
  * @param stakeAccountId - Stake account id.
@@ -62,15 +54,15 @@ const requireStakeAccountIds = async (
62
54
  */
63
55
  const requireStakeAccounts = async (
64
56
  ...params: [
65
- builder: ScallopBuilder,
57
+ ctx: SpoolActionContext,
66
58
  txBlock: SuiKitTxBlock,
67
59
  stakeMarketCoinName: string,
68
60
  stakeAccountId?: SuiAddressArg,
69
61
  ]
70
62
  ) => {
71
- const [builder, txBlock, stakeMarketCoinName, stakeAccountId] = params;
63
+ const [ctx, txBlock, stakeMarketCoinName, stakeAccountId] = params;
72
64
  const sender = requireSender(txBlock);
73
- const stakeAccounts = await getStakeAccounts(builder, sender);
65
+ const stakeAccounts = await ctx.reads.getAllStakeAccounts(sender);
74
66
  if (stakeAccounts[stakeMarketCoinName].length === 0) {
75
67
  throw new Error(`No stake account found for sender ${sender}`);
76
68
  }
@@ -85,7 +77,7 @@ const requireStakeAccounts = async (
85
77
  };
86
78
 
87
79
  const stakeHelper = async (
88
- builder: ScallopBuilder,
80
+ ctx: SpoolActionContext,
89
81
  txBlock: SuiTxBlockWithSpoolNormalMethods,
90
82
  stakeAccount: SuiAddressArg,
91
83
  coinName: string,
@@ -95,8 +87,8 @@ const stakeHelper = async (
95
87
  ) => {
96
88
  try {
97
89
  const { takeCoin, leftCoin, totalAmount } = isSCoin
98
- ? await builder.selectSCoin(txBlock, coinName, amount, sender)
99
- : await builder.selectMarketCoin(txBlock, coinName, amount, sender);
90
+ ? await ctx.coins.selectSCoin(txBlock, coinName, amount, sender)
91
+ : await ctx.coins.selectMarketCoin(txBlock, coinName, amount, sender);
100
92
  if (isSCoin) {
101
93
  const marketCoin = txBlock.burnSCoin(coinName, takeCoin);
102
94
  txBlock.stake(stakeAccount, marketCoin, coinName);
@@ -110,87 +102,6 @@ const stakeHelper = async (
110
102
  }
111
103
  };
112
104
 
113
- /**
114
- * Generate spool normal methods.
115
- *
116
- * @param builder - Scallop builder instance.
117
- * @param txBlock - TxBlock created by SuiKit .
118
- * @return Spool normal methods.
119
- */
120
- const generateSpoolNormalMethod: GenerateSpoolNormalMethod = ({
121
- builder,
122
- txBlock,
123
- }) => {
124
- const spoolIds: SpoolIds = {
125
- spoolPkg: builder.address.get('spool.id'),
126
- };
127
- const clockObjectRef = txBlock.sharedObjectRef({
128
- objectId: SUI_CLOCK_OBJECT_ID,
129
- mutable: false,
130
- initialSharedVersion: '1',
131
- });
132
-
133
- return {
134
- createStakeAccount: (stakeMarketCoinName) => {
135
- const marketCoinType =
136
- builder.utils.parseMarketCoinType(stakeMarketCoinName);
137
- const stakePoolId = builder.address.get(
138
- `spool.pools.${stakeMarketCoinName}.id`
139
- );
140
- return builder.moveCall(
141
- txBlock,
142
- `${spoolIds.spoolPkg}::user::new_spool_account`,
143
- [stakePoolId, clockObjectRef],
144
- [marketCoinType]
145
- );
146
- },
147
- stake: (stakeAccount, coin, stakeMarketCoinName) => {
148
- const marketCoinType =
149
- builder.utils.parseMarketCoinType(stakeMarketCoinName);
150
- const stakePoolId = builder.address.get(
151
- `spool.pools.${stakeMarketCoinName}.id`
152
- );
153
- builder.moveCall(
154
- txBlock,
155
- `${spoolIds.spoolPkg}::user::stake`,
156
- [stakePoolId, stakeAccount, coin, clockObjectRef],
157
- [marketCoinType]
158
- );
159
- },
160
- unstake: (stakeAccount, amount, stakeMarketCoinName) => {
161
- const marketCoinType =
162
- builder.utils.parseMarketCoinType(stakeMarketCoinName);
163
- const stakePoolId = builder.address.get(
164
- `spool.pools.${stakeMarketCoinName}.id`
165
- );
166
- return builder.moveCall(
167
- txBlock,
168
- `${spoolIds.spoolPkg}::user::unstake`,
169
- [stakePoolId, stakeAccount, amount, clockObjectRef],
170
- [marketCoinType]
171
- );
172
- },
173
- claim: (stakeAccount, stakeMarketCoinName) => {
174
- const stakePoolId = builder.address.get(
175
- `spool.pools.${stakeMarketCoinName}.id`
176
- ) as string;
177
- const rewardPoolId = builder.address.get(
178
- `spool.pools.${stakeMarketCoinName}.rewardPoolId`
179
- ) as string;
180
- const marketCoinType =
181
- builder.utils.parseMarketCoinType(stakeMarketCoinName);
182
- const rewardCoinName = builder.utils.getSpoolRewardCoinName();
183
- const rewardCoinType = builder.utils.parseCoinType(rewardCoinName);
184
- return builder.moveCall(
185
- txBlock,
186
- `${spoolIds.spoolPkg}::user::redeem_rewards`,
187
- [stakePoolId, rewardPoolId, stakeAccount, clockObjectRef],
188
- [marketCoinType, rewardCoinType]
189
- );
190
- },
191
- };
192
- };
193
-
194
105
  /**
195
106
  * Generate spool quick methods.
196
107
  *
@@ -199,12 +110,12 @@ const generateSpoolNormalMethod: GenerateSpoolNormalMethod = ({
199
110
  * help users organize transaction blocks, including getting stake account info, and transferring
200
111
  * coins to the sender. So, they are all asynchronous methods.
201
112
  *
202
- * @param builder - Scallop builder instance.
113
+ * @param ctx - Spool action context (reads, coins).
203
114
  * @param txBlock - TxBlock created by SuiKit .
204
115
  * @return Spool quick methods.
205
116
  */
206
- const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
207
- builder,
117
+ export const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
118
+ ctx,
208
119
  txBlock,
209
120
  }) => {
210
121
  return {
@@ -215,7 +126,7 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
215
126
  ) => {
216
127
  const sender = requireSender(txBlock);
217
128
  const stakeAccountIds = await requireStakeAccountIds(
218
- builder,
129
+ ctx,
219
130
  txBlock,
220
131
  stakeMarketCoinName,
221
132
  stakeAccountId
@@ -228,7 +139,7 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
228
139
  if (typeof amountOrMarketCoin === 'number') {
229
140
  // try stake market coin
230
141
  const stakedMarketCoinAmount = await stakeHelper(
231
- builder,
142
+ ctx,
232
143
  txBlock,
233
144
  stakeAccountIds[0],
234
145
  stakeMarketCoinName,
@@ -240,7 +151,7 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
240
151
  // no market coin, try sCoin
241
152
  if (amountOrMarketCoin > 0) {
242
153
  await stakeHelper(
243
- builder,
154
+ ctx,
244
155
  txBlock,
245
156
  stakeAccountIds[0],
246
157
  stakeMarketCoinName,
@@ -264,7 +175,7 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
264
175
  returnSCoin = true
265
176
  ) => {
266
177
  const stakeAccounts = await requireStakeAccounts(
267
- builder,
178
+ ctx,
268
179
  txBlock,
269
180
  stakeMarketCoinName,
270
181
  stakeAccountId
@@ -302,7 +213,7 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
302
213
  },
303
214
  claimQuick: async (stakeMarketCoinName, stakeAccountId) => {
304
215
  const stakeAccountIds = await requireStakeAccountIds(
305
- builder,
216
+ ctx,
306
217
  txBlock,
307
218
  stakeMarketCoinName,
308
219
  stakeAccountId
@@ -316,54 +227,3 @@ const generateSpoolQuickMethod: GenerateSpoolQuickMethod = ({
316
227
  },
317
228
  };
318
229
  };
319
-
320
- /**
321
- * Create an enhanced transaction block instance for interaction with spool modules of the Scallop contract.
322
- *
323
- * @param builder - Scallop builder instance.
324
- * @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
325
- * @return Scallop spool txBlock.
326
- */
327
- export const newSpoolTxBlock = (
328
- builder: ScallopBuilder,
329
- initTxBlock?:
330
- | ScallopTxBlock
331
- | SuiKitTxBlock
332
- | Transaction
333
- | SuiTxBlockWithSCoin
334
- ) => {
335
- const txBlock =
336
- initTxBlock instanceof Transaction
337
- ? new SuiKitTxBlock(initTxBlock)
338
- : initTxBlock
339
- ? initTxBlock
340
- : new SuiKitTxBlock();
341
-
342
- const normalMethod = generateSpoolNormalMethod({
343
- builder,
344
- txBlock,
345
- });
346
-
347
- const normalTxBlock = new Proxy(txBlock, {
348
- get: (target, prop) => {
349
- if (prop in normalMethod) {
350
- return Reflect.get(normalMethod, prop);
351
- }
352
- return Reflect.get(target, prop);
353
- },
354
- }) as SuiTxBlockWithSpoolNormalMethods;
355
-
356
- const quickMethod = generateSpoolQuickMethod({
357
- builder,
358
- txBlock: normalTxBlock,
359
- });
360
-
361
- return new Proxy(normalTxBlock, {
362
- get: (target, prop) => {
363
- if (prop in quickMethod) {
364
- return Reflect.get(quickMethod, prop);
365
- }
366
- return Reflect.get(target, prop);
367
- },
368
- }) as SpoolTxBlock;
369
- };
@@ -0,0 +1,36 @@
1
+ import { SuiObjectArg } from '@scallop-io/sui-kit';
2
+ import { ScallopParseError } from 'src/errors/ScallopParseError.js';
3
+ import ScallopBuilder from 'src/models/scallopBuilder/index.js';
4
+
5
+ export const getObligationCoinNames = async (
6
+ builder: ScallopBuilder,
7
+ obligationId: SuiObjectArg
8
+ ) => {
9
+ const id =
10
+ typeof obligationId === 'string'
11
+ ? obligationId
12
+ : 'objectId' in obligationId
13
+ ? obligationId.objectId
14
+ : undefined;
15
+ if (id === undefined) {
16
+ throw new ScallopParseError(
17
+ 'getObligationCoinNames expects an object id (string) or an object reference'
18
+ );
19
+ }
20
+ const obligation = await builder.query.repos.obligation.getObligationData(id);
21
+ if (!obligation) return undefined;
22
+
23
+ const collateralCoinTypes = obligation.collaterals.map((collateral) => {
24
+ return collateral.type;
25
+ });
26
+ const debtCoinTypes = obligation.debts.map((debt) => {
27
+ return debt.type;
28
+ });
29
+ const obligationCoinTypes = [
30
+ ...new Set([...collateralCoinTypes, ...debtCoinTypes]),
31
+ ];
32
+ const obligationCoinNames = obligationCoinTypes.map((coinType) => {
33
+ return builder.utils.parseCoinNameFromType(coinType);
34
+ });
35
+ return obligationCoinNames;
36
+ };
@@ -0,0 +1,45 @@
1
+ import type { Logger } from 'src/logger/index.js';
2
+ import {
3
+ TX_BLOCK_MANIFEST,
4
+ detectManifestCollisions,
5
+ type TxBlockManifest,
6
+ } from './manifest.js';
7
+
8
+ export type VerifyTxBlockResult = {
9
+ collisions: ReturnType<typeof detectManifestCollisions>;
10
+ missing: { module: string; method: string }[];
11
+ };
12
+
13
+ export const verifyTxBlockMethods = (
14
+ txBlock: object,
15
+ manifest: TxBlockManifest = TX_BLOCK_MANIFEST,
16
+ logger?: Logger
17
+ ): VerifyTxBlockResult => {
18
+ const collisions = detectManifestCollisions(manifest);
19
+ const missing: VerifyTxBlockResult['missing'] = [];
20
+
21
+ for (const [moduleName, methods] of Object.entries(manifest)) {
22
+ for (const method of methods) {
23
+ const value = (txBlock as Record<string, unknown>)[method];
24
+ if (typeof value !== 'function') {
25
+ missing.push({ module: moduleName, method });
26
+ }
27
+ }
28
+ }
29
+
30
+ if (logger) {
31
+ if (collisions.length) {
32
+ logger.warn('Tx-block manifest collisions detected', {
33
+ collisions: collisions.map((c) => ({
34
+ method: c.method,
35
+ modules: c.modules,
36
+ })),
37
+ });
38
+ }
39
+ if (missing.length) {
40
+ logger.warn('Tx-block manifest methods missing at runtime', { missing });
41
+ }
42
+ }
43
+
44
+ return { collisions, missing };
45
+ };
@@ -0,0 +1,75 @@
1
+ import { Transaction, SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
2
+ import { ScallopBuilder } from 'src/models/index.js';
3
+ import { generateNormalVeScaMethod } from './moveCalls.js';
4
+ import { generateQuickVeScaMethod, type VeScaActionContext } from './quick.js';
5
+ import type {
6
+ ScallopTxBlock,
7
+ SuiTxBlockWithVeScaNormalMethods,
8
+ VeScaTxBlock,
9
+ } from 'src/types/index.js';
10
+ import type { MoveCallContext } from '../context.js';
11
+
12
+ /**
13
+ * Create an enhanced transaction block instance for interaction with veSCA modules of the Scallop contract.
14
+ *
15
+ * @param builder - Scallop builder instance.
16
+ * @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
17
+ * @return Scallop borrow incentive txBlock.
18
+ */
19
+ export const newVeScaTxBlock = (
20
+ builder: ScallopBuilder,
21
+ initTxBlock?: ScallopTxBlock | SuiKitTxBlock | Transaction
22
+ ) => {
23
+ const txBlock =
24
+ initTxBlock instanceof Transaction
25
+ ? new SuiKitTxBlock(initTxBlock)
26
+ : initTxBlock
27
+ ? initTxBlock
28
+ : new SuiKitTxBlock();
29
+
30
+ // Build the narrow contexts once from `builder`, binding the closures.
31
+ const moveCallContext: MoveCallContext = {
32
+ address: builder.address,
33
+ moveCall: builder.moveCall.bind(builder),
34
+ utils: builder.utils,
35
+ };
36
+
37
+ const actionContext: VeScaActionContext = {
38
+ address: builder.address,
39
+ utils: builder.utils,
40
+ reads: {
41
+ getVeSca: (veScaKey) => builder.query.getVeSca(veScaKey),
42
+ getVeScas: (input) => builder.query.getVeScas(input),
43
+ isVeScaKeyInSubsTable: (veScaKey, tableId) =>
44
+ builder.query.repos.veSca.isVeScaKeyInSubsTable(veScaKey, tableId),
45
+ },
46
+ };
47
+
48
+ const normalMethod = generateNormalVeScaMethod({
49
+ ctx: moveCallContext,
50
+ txBlock,
51
+ });
52
+
53
+ const normalTxBlock = new Proxy(txBlock, {
54
+ get: (target, prop) => {
55
+ if (prop in normalMethod) {
56
+ return Reflect.get(normalMethod, prop);
57
+ }
58
+ return Reflect.get(target, prop);
59
+ },
60
+ }) as SuiTxBlockWithVeScaNormalMethods;
61
+
62
+ const quickMethod = generateQuickVeScaMethod({
63
+ ctx: actionContext,
64
+ txBlock: normalTxBlock,
65
+ });
66
+
67
+ return new Proxy(normalTxBlock, {
68
+ get: (target, prop) => {
69
+ if (prop in quickMethod) {
70
+ return Reflect.get(quickMethod, prop);
71
+ }
72
+ return Reflect.get(target, prop);
73
+ },
74
+ }) as VeScaTxBlock;
75
+ };