@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,147 @@
1
+ import { SUI_CLOCK_OBJECT_ID } from '@scallop-io/sui-kit';
2
+ import type {
3
+ AddressesInterface,
4
+ GenerateVeScaNormalMethod,
5
+ } from 'src/types/index.js';
6
+
7
+ type VeScaProps = 'id' | 'table' | 'treasury' | 'config' | 'subsTable';
8
+
9
+ /**
10
+ * Generate veSCA normal methods.
11
+ *
12
+ * @param ctx - Pure Move-call context (address reads, coin-type parsing, moveCall).
13
+ * @param txBlock - TxBlock created by SuiKit .
14
+ * @return veSCA normal methods.
15
+ */
16
+ export const generateNormalVeScaMethod: GenerateVeScaNormalMethod = ({
17
+ ctx,
18
+ txBlock,
19
+ }) => {
20
+ const veScaIds: Pick<AddressesInterface['vesca'], VeScaProps> = {
21
+ id: ctx.address.get('vesca.id'),
22
+ table: ctx.address.get('vesca.table'),
23
+ treasury: ctx.address.get('vesca.treasury'),
24
+ config: ctx.address.get('vesca.config'),
25
+ subsTable: ctx.address.get('vesca.subsTable'),
26
+ };
27
+
28
+ const clockObjectRef = txBlock.sharedObjectRef({
29
+ objectId: SUI_CLOCK_OBJECT_ID,
30
+ mutable: false,
31
+ initialSharedVersion: '1',
32
+ });
33
+
34
+ return {
35
+ lockSca: (scaCoin, unlockAtInSecondTimestamp) => {
36
+ return ctx.moveCall(
37
+ txBlock,
38
+ `${veScaIds.id}::ve_sca::mint_ve_sca_key`,
39
+ [
40
+ veScaIds.config,
41
+ veScaIds.table,
42
+ veScaIds.treasury,
43
+ scaCoin,
44
+ unlockAtInSecondTimestamp,
45
+ clockObjectRef,
46
+ ],
47
+ []
48
+ );
49
+ },
50
+ extendLockPeriod: (veScaKey, newUnlockAtInSecondTimestamp) => {
51
+ ctx.moveCall(
52
+ txBlock,
53
+ `${veScaIds.id}::ve_sca::extend_lock_period`,
54
+ [
55
+ veScaIds.config,
56
+ veScaKey,
57
+ veScaIds.table,
58
+ veScaIds.treasury,
59
+ newUnlockAtInSecondTimestamp,
60
+ clockObjectRef,
61
+ ],
62
+ []
63
+ );
64
+ },
65
+ extendLockAmount: (veScaKey, scaCoin) => {
66
+ ctx.moveCall(
67
+ txBlock,
68
+ `${veScaIds.id}::ve_sca::lock_more_sca`,
69
+ [
70
+ veScaIds.config,
71
+ veScaKey,
72
+ veScaIds.table,
73
+ veScaIds.treasury,
74
+ scaCoin,
75
+ clockObjectRef,
76
+ ],
77
+ []
78
+ );
79
+ },
80
+ renewExpiredVeSca: (veScaKey, scaCoin, newUnlockAtInSecondTimestamp) => {
81
+ ctx.moveCall(
82
+ txBlock,
83
+ `${veScaIds.id}::ve_sca::renew_expired_ve_sca`,
84
+ [
85
+ veScaIds.config,
86
+ veScaKey,
87
+ veScaIds.table,
88
+ veScaIds.treasury,
89
+ scaCoin,
90
+ newUnlockAtInSecondTimestamp,
91
+ clockObjectRef,
92
+ ],
93
+ []
94
+ );
95
+ },
96
+ redeemSca: (veScaKey) => {
97
+ return ctx.moveCall(
98
+ txBlock,
99
+ `${veScaIds.id}::ve_sca::redeem`,
100
+ [
101
+ veScaIds.config,
102
+ veScaKey,
103
+ veScaIds.table,
104
+ veScaIds.treasury,
105
+ clockObjectRef,
106
+ ],
107
+ []
108
+ );
109
+ },
110
+ mintEmptyVeSca: () => {
111
+ return ctx.moveCall(
112
+ txBlock,
113
+ `${veScaIds.id}::ve_sca::mint_ve_sca_placeholder_key`,
114
+ [veScaIds.config, veScaIds.table],
115
+ []
116
+ );
117
+ },
118
+ splitVeSca: (veScaKey, splitAmount) => {
119
+ return ctx.moveCall(txBlock, `${veScaIds.id}::ve_sca::split`, [
120
+ veScaIds.config,
121
+ veScaKey,
122
+ veScaIds.table,
123
+ veScaIds.subsTable,
124
+ txBlock.pure.u64(splitAmount),
125
+ ]);
126
+ },
127
+ mergeVeSca: (targetKey, sourceKey) => {
128
+ return ctx.moveCall(
129
+ txBlock,
130
+ `${veScaIds.id}::ve_sca::merge`,
131
+ [
132
+ veScaIds.config,
133
+ targetKey,
134
+ sourceKey,
135
+ veScaIds.table,
136
+ veScaIds.subsTable,
137
+ txBlock.sharedObjectRef({
138
+ objectId: SUI_CLOCK_OBJECT_ID,
139
+ mutable: false,
140
+ initialSharedVersion: '1',
141
+ }),
142
+ ],
143
+ []
144
+ );
145
+ },
146
+ };
147
+ };
@@ -1,12 +1,5 @@
1
- import {
2
- SUI_CLOCK_OBJECT_ID,
3
- SuiTxBlock,
4
- Transaction,
5
- SuiTxBlock as SuiKitTxBlock,
6
- } from '@scallop-io/sui-kit';
1
+ import { SuiTxBlock } from '@scallop-io/sui-kit';
7
2
  import { SCA_COIN_TYPE } from 'src/constants/index.js';
8
- import { ScallopBuilder } from 'src/models/index.js';
9
- import { getVeSca, getVeScas } from 'src/queries/index.js';
10
3
  import {
11
4
  requireSender,
12
5
  checkLockSca,
@@ -15,25 +8,38 @@ import {
15
8
  checkRenewExpiredVeSca,
16
9
  checkVesca,
17
10
  getMoveCallTarget,
18
- parseObjectAs,
19
- } from 'src/utils/index.js';
11
+ } from '../../utils/builder.js';
20
12
  import type {
21
13
  TransactionObjectArgument,
22
14
  SuiObjectArg,
23
15
  } from '@scallop-io/sui-kit';
16
+ import type { ScallopAddress, ScallopBuilder } from 'src/models/index.js';
24
17
  import type {
25
- AddressesInterface,
26
- DynamicFieldResponseWithContents,
27
- GenerateVeScaNormalMethod,
28
18
  GenerateVeScaQuickMethod,
29
19
  QuickMethodReturnType,
30
- ScallopTxBlock,
31
- SuiTxBlockWithVeScaNormalMethods,
32
20
  TransactionCommand,
33
- VeScaTxBlock,
34
21
  } from 'src/types/index.js';
35
22
  import type { SuiObjectData } from 'src/types/index.js';
36
23
 
24
+ /**
25
+ * The explicit orchestration toolkit a veSCA quick method needs.
26
+ *
27
+ * @description
28
+ * Narrow context injected into {@link generateQuickVeScaMethod}. Built once from
29
+ * `builder` in the factory and passed (instead of `builder`) into the quick
30
+ * generator. Method signatures are taken via indexed-access types so they stay
31
+ * in sync with `ScallopBuilder`.
32
+ */
33
+ export type VeScaActionContext = {
34
+ address: Pick<ScallopAddress, 'get'>;
35
+ utils: ScallopBuilder['utils'];
36
+ reads: {
37
+ getVeSca: ScallopBuilder['query']['getVeSca'];
38
+ getVeScas: ScallopBuilder['query']['getVeScas'];
39
+ isVeScaKeyInSubsTable: ScallopBuilder['query']['repos']['veSca']['isVeScaKeyInSubsTable'];
40
+ };
41
+ };
42
+
37
43
  /**
38
44
  * Check and get veSCA data from transaction block.
39
45
  *
@@ -41,7 +47,7 @@ import type { SuiObjectData } from 'src/types/index.js';
41
47
  * If the veScaKey id is provided, directly return it.
42
48
  * Otherwise, automatically get veScaKey from the sender.
43
49
  *
44
- * @param builder - Scallop builder instance.
50
+ * @param ctx - veSCA action context (provides `reads.getVeSca` / `reads.getVeScas`).
45
51
  * @param txBlock - TxBlock created by SuiKit.
46
52
  * @param veScaKey - veSCA key.
47
53
  * @return veSCA key, ID, locked amount and unlock at timestamp.
@@ -49,14 +55,14 @@ import type { SuiObjectData } from 'src/types/index.js';
49
55
 
50
56
  export const requireVeSca = async (
51
57
  ...params: [
52
- builder: ScallopBuilder,
58
+ ctx: VeScaActionContext,
53
59
  SuiTxBlock: SuiTxBlock,
54
60
  veScaKey?: SuiObjectData | string,
55
61
  ]
56
62
  ) => {
57
- const [builder, txBlock, veScaKey] = params;
63
+ const [ctx, txBlock, veScaKey] = params;
58
64
  if (params.length === 3 && veScaKey && typeof veScaKey !== 'undefined') {
59
- const veSca = await getVeSca(builder.utils, veScaKey);
65
+ const veSca = await ctx.reads.getVeSca(veScaKey);
60
66
 
61
67
  if (!veSca) {
62
68
  return undefined;
@@ -66,7 +72,7 @@ export const requireVeSca = async (
66
72
  }
67
73
 
68
74
  const sender = requireSender(txBlock);
69
- const veScas = await getVeScas(builder, sender);
75
+ const veScas = await ctx.reads.getVeScas({ walletAddress: sender });
70
76
  if (veScas.length === 0) {
71
77
  return undefined;
72
78
  }
@@ -82,172 +88,21 @@ export const requireVeSca = async (
82
88
  };
83
89
 
84
90
  export const isInSubsTable = async (
85
- ...params: [builder: ScallopBuilder, veScaKey: string, tableId: string]
91
+ ...params: [ctx: VeScaActionContext, veScaKey: string, tableId: string]
86
92
  ) => {
87
- const [builder, veScaKey, tableId] = params;
93
+ const [ctx, veScaKey, tableId] = params;
88
94
  try {
89
- const resp = (await builder.scallopSuiKit.queryGetDynamicFieldObject({
90
- parentId: tableId,
91
- name: {
92
- type: '0x2::object::ID',
93
- value: veScaKey,
94
- },
95
- })) as DynamicFieldResponseWithContents;
96
-
97
- if (!resp?.object?.json) return false;
98
-
99
- const value = parseObjectAs<{ contents?: unknown[] }>(
100
- resp.object as SuiObjectData
101
- );
102
- return Array.isArray(value?.contents) && value.contents.length > 0;
95
+ return await ctx.reads.isVeScaKeyInSubsTable(veScaKey, tableId);
103
96
  } catch (e) {
104
- console.error(e);
97
+ ctx.utils.logger.error('isInSubsTable lookup failed', {
98
+ veScaKey,
99
+ tableId,
100
+ message: (e as Error)?.message,
101
+ });
105
102
  return false;
106
103
  }
107
104
  };
108
105
 
109
- type VeScaProps = 'id' | 'table' | 'treasury' | 'config' | 'subsTable';
110
-
111
- /**
112
- * Generate veSCA normal methods.
113
- *
114
- * @param builder - Scallop builder instance.
115
- * @param txBlock - TxBlock created by SuiKit .
116
- * @return veSCA normal methods.
117
- */
118
- const generateNormalVeScaMethod: GenerateVeScaNormalMethod = ({
119
- builder,
120
- txBlock,
121
- }) => {
122
- const veScaIds: Pick<AddressesInterface['vesca'], VeScaProps> = {
123
- id: builder.address.get('vesca.id'),
124
- table: builder.address.get('vesca.table'),
125
- treasury: builder.address.get('vesca.treasury'),
126
- config: builder.address.get('vesca.config'),
127
- subsTable: builder.address.get('vesca.subsTable'),
128
- };
129
-
130
- const clockObjectRef = txBlock.sharedObjectRef({
131
- objectId: SUI_CLOCK_OBJECT_ID,
132
- mutable: false,
133
- initialSharedVersion: '1',
134
- });
135
-
136
- return {
137
- lockSca: (scaCoin, unlockAtInSecondTimestamp) => {
138
- return builder.moveCall(
139
- txBlock,
140
- `${veScaIds.id}::ve_sca::mint_ve_sca_key`,
141
- [
142
- veScaIds.config,
143
- veScaIds.table,
144
- veScaIds.treasury,
145
- scaCoin,
146
- unlockAtInSecondTimestamp,
147
- clockObjectRef,
148
- ],
149
- []
150
- );
151
- },
152
- extendLockPeriod: (veScaKey, newUnlockAtInSecondTimestamp) => {
153
- builder.moveCall(
154
- txBlock,
155
- `${veScaIds.id}::ve_sca::extend_lock_period`,
156
- [
157
- veScaIds.config,
158
- veScaKey,
159
- veScaIds.table,
160
- veScaIds.treasury,
161
- newUnlockAtInSecondTimestamp,
162
- clockObjectRef,
163
- ],
164
- []
165
- );
166
- },
167
- extendLockAmount: (veScaKey, scaCoin) => {
168
- builder.moveCall(
169
- txBlock,
170
- `${veScaIds.id}::ve_sca::lock_more_sca`,
171
- [
172
- veScaIds.config,
173
- veScaKey,
174
- veScaIds.table,
175
- veScaIds.treasury,
176
- scaCoin,
177
- clockObjectRef,
178
- ],
179
- []
180
- );
181
- },
182
- renewExpiredVeSca: (veScaKey, scaCoin, newUnlockAtInSecondTimestamp) => {
183
- builder.moveCall(
184
- txBlock,
185
- `${veScaIds.id}::ve_sca::renew_expired_ve_sca`,
186
- [
187
- veScaIds.config,
188
- veScaKey,
189
- veScaIds.table,
190
- veScaIds.treasury,
191
- scaCoin,
192
- newUnlockAtInSecondTimestamp,
193
- clockObjectRef,
194
- ],
195
- []
196
- );
197
- },
198
- redeemSca: (veScaKey) => {
199
- return builder.moveCall(
200
- txBlock,
201
- `${veScaIds.id}::ve_sca::redeem`,
202
- [
203
- veScaIds.config,
204
- veScaKey,
205
- veScaIds.table,
206
- veScaIds.treasury,
207
- clockObjectRef,
208
- ],
209
- []
210
- );
211
- },
212
- mintEmptyVeSca: () => {
213
- return builder.moveCall(
214
- txBlock,
215
- `${veScaIds.id}::ve_sca::mint_ve_sca_placeholder_key`,
216
- [veScaIds.config, veScaIds.table],
217
- []
218
- );
219
- },
220
- splitVeSca: (veScaKey, splitAmount) => {
221
- return builder.moveCall(txBlock, `${veScaIds.id}::ve_sca::split`, [
222
- veScaIds.config,
223
- veScaKey,
224
- veScaIds.table,
225
- veScaIds.subsTable,
226
- txBlock.pure.u64(splitAmount),
227
- ]);
228
- },
229
- mergeVeSca: (targetKey, sourceKey) => {
230
- return builder.moveCall(
231
- txBlock,
232
- `${veScaIds.id}::ve_sca::merge`,
233
- [
234
- veScaIds.config,
235
- targetKey,
236
- sourceKey,
237
- veScaIds.table,
238
- veScaIds.subsTable,
239
- txBlock.sharedObjectRef({
240
- objectId: SUI_CLOCK_OBJECT_ID,
241
- mutable: false,
242
- initialSharedVersion: '1',
243
- }),
244
- ],
245
- []
246
- );
247
- },
248
- };
249
- };
250
-
251
106
  /**
252
107
  * Generate veSCA quick methods.
253
108
  *
@@ -256,12 +111,12 @@ const generateNormalVeScaMethod: GenerateVeScaNormalMethod = ({
256
111
  * help users organize transaction blocks, include get veSca info, and transfer
257
112
  * coins to the sender. So, they are all asynchronous methods.
258
113
  *
259
- * @param builder - Scallop builder instance.
114
+ * @param ctx - veSCA action context (address, utils, reads).
260
115
  * @param txBlock - TxBlock created by SuiKit .
261
116
  * @return veSCA quick methods.
262
117
  */
263
- const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
264
- builder,
118
+ export const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
119
+ ctx,
265
120
  txBlock,
266
121
  }) => {
267
122
  return {
@@ -272,17 +127,33 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
272
127
  veScaKey,
273
128
  }) => {
274
129
  const sender = requireSender(txBlock);
275
- const veSca = await requireVeSca(builder, txBlock, veScaKey);
130
+ const veSca = await requireVeSca(ctx, txBlock, veScaKey);
131
+
132
+ const newUnlockAt = ctx.utils.getUnlockAt(
133
+ lockPeriodInDays,
134
+ veSca?.unlockAt
135
+ );
136
+
137
+ // Validate before side effects (coin selection) so input-shape errors
138
+ // surface as the documented validation error, not a downstream
139
+ // "No valid coins" from selectCoins.
140
+ if (autoCheck)
141
+ checkLockSca(
142
+ amountOrCoin,
143
+ lockPeriodInDays,
144
+ newUnlockAt,
145
+ veSca?.unlockAt
146
+ );
276
147
 
277
148
  let scaCoin: TransactionObjectArgument | SuiObjectArg | undefined =
278
149
  undefined;
279
150
  const transferObjects = [];
280
151
  if (amountOrCoin !== undefined && typeof amountOrCoin === 'number') {
281
- const coins = await builder.utils.selectCoins(
282
- amountOrCoin,
283
- SCA_COIN_TYPE,
284
- sender
285
- );
152
+ const coins = await ctx.utils.selectCoins({
153
+ amount: amountOrCoin,
154
+ coinType: SCA_COIN_TYPE,
155
+ ownerAddress: sender,
156
+ });
286
157
  const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
287
158
  coins,
288
159
  amountOrCoin
@@ -294,19 +165,6 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
294
165
  scaCoin = amountOrCoin;
295
166
  }
296
167
 
297
- const newUnlockAt = builder.utils.getUnlockAt(
298
- lockPeriodInDays,
299
- veSca?.unlockAt
300
- );
301
-
302
- if (autoCheck)
303
- checkLockSca(
304
- amountOrCoin,
305
- lockPeriodInDays,
306
- newUnlockAt,
307
- veSca?.unlockAt
308
- );
309
-
310
168
  const isInitialLock = !veSca;
311
169
  const isLockExpired =
312
170
  !isInitialLock && veSca.unlockAt <= new Date().getTime();
@@ -345,8 +203,8 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
345
203
  veScaKey,
346
204
  autoCheck = true,
347
205
  }) => {
348
- const veSca = await requireVeSca(builder, txBlock, veScaKey);
349
- const newUnlockAt = builder.utils.getUnlockAt(
206
+ const veSca = await requireVeSca(ctx, txBlock, veScaKey);
207
+ const newUnlockAt = ctx.utils.getUnlockAt(
350
208
  lockPeriodInDays,
351
209
  veSca?.unlockAt
352
210
  );
@@ -364,16 +222,16 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
364
222
  autoCheck = true,
365
223
  }) => {
366
224
  const sender = requireSender(txBlock);
367
- const veSca = await requireVeSca(builder, txBlock, veScaKey);
225
+ const veSca = await requireVeSca(ctx, txBlock, veScaKey);
368
226
 
369
227
  if (autoCheck) checkExtendLockAmount(scaAmount, veSca?.unlockAt);
370
228
 
371
229
  if (veSca) {
372
- const scaCoins = await builder.utils.selectCoins(
373
- scaAmount,
374
- SCA_COIN_TYPE,
375
- sender
376
- );
230
+ const scaCoins = await ctx.utils.selectCoins({
231
+ amount: scaAmount,
232
+ coinType: SCA_COIN_TYPE,
233
+ ownerAddress: sender,
234
+ });
377
235
  const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
378
236
  scaCoins,
379
237
  scaAmount
@@ -390,9 +248,9 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
390
248
  autoCheck = true,
391
249
  }) => {
392
250
  const sender = requireSender(txBlock);
393
- const veSca = await requireVeSca(builder, txBlock, veScaKey);
251
+ const veSca = await requireVeSca(ctx, txBlock, veScaKey);
394
252
 
395
- const newUnlockAt = builder.utils.getUnlockAt(
253
+ const newUnlockAt = ctx.utils.getUnlockAt(
396
254
  lockPeriodInDays,
397
255
  veSca?.unlockAt
398
256
  );
@@ -405,11 +263,11 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
405
263
  const unlockedSca = txBlock.redeemSca(veSca.keyId);
406
264
  transferObjects.push(unlockedSca);
407
265
  }
408
- const scaCoins = await builder.utils.selectCoins(
409
- scaAmount,
410
- SCA_COIN_TYPE,
411
- sender
412
- );
266
+ const scaCoins = await ctx.utils.selectCoins({
267
+ amount: scaAmount,
268
+ coinType: SCA_COIN_TYPE,
269
+ ownerAddress: sender,
270
+ });
413
271
  const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
414
272
  scaCoins,
415
273
  scaAmount
@@ -428,7 +286,7 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
428
286
  transferSca?: T;
429
287
  }) => {
430
288
  const sender = requireSender(txBlock);
431
- const veSca = await requireVeSca(builder, txBlock, veScaKey);
289
+ const veSca = await requireVeSca(ctx, txBlock, veScaKey);
432
290
 
433
291
  checkVesca(veSca?.unlockAt);
434
292
 
@@ -451,9 +309,9 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
451
309
  transferVeScaKey?: S;
452
310
  }) => {
453
311
  const isKeyInSubTable = await isInSubsTable(
454
- builder,
312
+ ctx,
455
313
  veScaKey,
456
- builder.address.get('vesca.subsTable')
314
+ ctx.address.get('vesca.subsTable')
457
315
  );
458
316
 
459
317
  const unstakeObligationBeforeStake = !!txBlock.txBlock
@@ -462,7 +320,7 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
462
320
  (txn: TransactionCommand) =>
463
321
  txn.$kind === 'MoveCall' &&
464
322
  getMoveCallTarget(txn) ===
465
- `${builder.address.get('borrowIncentive.id')}::user::unstake_v2`
323
+ `${ctx.address.get('borrowIncentive.id')}::user::unstake_v2`
466
324
  );
467
325
 
468
326
  if (isKeyInSubTable && !unstakeObligationBeforeStake) {
@@ -481,10 +339,10 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
481
339
  },
482
340
  mergeVeScaQuick: async ({ targetVeScaKey, sourceVeScaKey }) => {
483
341
  // check targetKey and sourceKey
484
- const table = builder.address.get('vesca.subsTableId');
342
+ const table = ctx.address.get('vesca.subsTableId');
485
343
  const [isTargetInSubTable, isSourceInSubTable] = await Promise.all([
486
- isInSubsTable(builder, targetVeScaKey, table),
487
- isInSubsTable(builder, sourceVeScaKey, table),
344
+ isInSubsTable(ctx, targetVeScaKey, table),
345
+ isInSubsTable(ctx, sourceVeScaKey, table),
488
346
  ]);
489
347
 
490
348
  const unstakeObligationBeforeStake = !!txBlock.txBlock
@@ -493,7 +351,7 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
493
351
  (txn: TransactionCommand) =>
494
352
  txn.$kind === 'MoveCall' &&
495
353
  getMoveCallTarget(txn) ===
496
- `${builder.address.get('borrowIncentive.id')}::user::unstake_v2`
354
+ `${ctx.address.get('borrowIncentive.id')}::user::unstake_v2`
497
355
  );
498
356
 
499
357
  if (
@@ -506,8 +364,8 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
506
364
  }
507
365
 
508
366
  const [sourceVesca, targetVesca] = await Promise.all([
509
- getVeSca(builder.utils, sourceVeScaKey),
510
- getVeSca(builder.utils, targetVeScaKey),
367
+ ctx.reads.getVeSca(sourceVeScaKey),
368
+ ctx.reads.getVeSca(targetVeScaKey),
511
369
  ]);
512
370
 
513
371
  if (!sourceVesca || !targetVesca) {
@@ -531,50 +389,3 @@ const generateQuickVeScaMethod: GenerateVeScaQuickMethod = ({
531
389
  },
532
390
  };
533
391
  };
534
-
535
- /**
536
- * Create an enhanced transaction block instance for interaction with veSCA modules of the Scallop contract.
537
- *
538
- * @param builder - Scallop builder instance.
539
- * @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
540
- * @return Scallop borrow incentive txBlock.
541
- */
542
- export const newVeScaTxBlock = (
543
- builder: ScallopBuilder,
544
- initTxBlock?: ScallopTxBlock | SuiKitTxBlock | Transaction
545
- ) => {
546
- const txBlock =
547
- initTxBlock instanceof Transaction
548
- ? new SuiKitTxBlock(initTxBlock)
549
- : initTxBlock
550
- ? initTxBlock
551
- : new SuiKitTxBlock();
552
-
553
- const normalMethod = generateNormalVeScaMethod({
554
- builder,
555
- txBlock,
556
- });
557
-
558
- const normalTxBlock = new Proxy(txBlock, {
559
- get: (target, prop) => {
560
- if (prop in normalMethod) {
561
- return Reflect.get(normalMethod, prop);
562
- }
563
- return Reflect.get(target, prop);
564
- },
565
- }) as SuiTxBlockWithVeScaNormalMethods;
566
-
567
- const quickMethod = generateQuickVeScaMethod({
568
- builder,
569
- txBlock: normalTxBlock,
570
- });
571
-
572
- return new Proxy(normalTxBlock, {
573
- get: (target, prop) => {
574
- if (prop in quickMethod) {
575
- return Reflect.get(quickMethod, prop);
576
- }
577
- return Reflect.get(target, prop);
578
- },
579
- }) as VeScaTxBlock;
580
- };