create-dubhe 1.2.0-pre.98 → 2.0.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 (361) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +16 -16
  4. package/templates/101/sui-template/docker-compose.testnet.yml +73 -0
  5. package/templates/101/sui-template/packages/client/src/app/page.tsx +545 -41
  6. package/templates/101/sui-template/packages/client/src/app/providers.tsx +12 -4
  7. package/templates/101/sui-template/packages/contracts/Pub.localnet.toml +4 -4
  8. package/templates/101/sui-template/packages/contracts/counter.lock.json +20 -0
  9. package/templates/101/sui-template/packages/contracts/deployment.ts +8 -3
  10. package/templates/101/sui-template/packages/contracts/dubhe.config.json +59 -13
  11. package/templates/101/sui-template/packages/contracts/dubhe.config.ts +1 -4
  12. package/templates/101/sui-template/packages/contracts/metadata.json +1015 -68
  13. package/templates/101/sui-template/packages/contracts/package.json +7 -4
  14. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/dapp_key.move +45 -31
  15. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/error.move +8 -0
  16. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/genesis.move +30 -13
  17. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/init_test.move +19 -14
  18. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter2.move +198 -0
  19. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter2withkey.move +90 -0
  20. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/resources/value.move +30 -20
  21. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/user_storage_init.move +26 -0
  22. package/templates/101/sui-template/packages/contracts/src/counter/sources/scripts/deploy_hook.move +6 -11
  23. package/templates/101/sui-template/packages/contracts/src/counter/sources/systems/counter.move +23 -11
  24. package/templates/101/sui-template/packages/contracts/src/counter/sources/tests/counter.move +15 -14
  25. package/templates/101/sui-template/packages/contracts/src/dubhe/Move.lock +33 -30
  26. package/templates/101/sui-template/packages/contracts/src/dubhe/Move.toml +8 -3
  27. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move +45 -31
  28. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/error.move +170 -0
  29. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/genesis.move +16 -13
  30. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/init_test.move +8 -14
  31. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/account_key.move +1 -3
  32. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move +1776 -137
  33. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/data_key.move +1 -20
  34. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/events.move +864 -25
  35. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/scripts/deploy_hook.move +15 -16
  36. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/scripts/migrate.move +0 -3
  37. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/address_system.move +25 -17
  38. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +2802 -343
  39. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/utils.move +1 -1
  40. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/address.move +173 -55
  41. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/dapp_test.move +769 -0
  42. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +2965 -0
  43. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move +303 -0
  44. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/listing_test.move +1422 -0
  45. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/scene_session_test.move +269 -0
  46. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/session_test.move +624 -0
  47. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/storage_test.move +700 -0
  48. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/typed_object_test.move +177 -0
  49. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/typed_scene_test.move +452 -0
  50. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/user_storage_test.move +160 -0
  51. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/utils/math.move +4 -3
  52. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/utils/type_info.move +2 -2
  53. package/templates/contract/sui-template/dubhe.config.ts +0 -1
  54. package/templates/contract/sui-template/package.json +3 -3
  55. package/templates/contract/sui-template/src/dubhe/Move.lock +33 -30
  56. package/templates/contract/sui-template/src/dubhe/Move.toml +8 -3
  57. package/templates/contract/sui-template/src/dubhe/sources/codegen/dapp_key.move +45 -31
  58. package/templates/contract/sui-template/src/dubhe/sources/codegen/error.move +170 -0
  59. package/templates/contract/sui-template/src/dubhe/sources/codegen/genesis.move +16 -13
  60. package/templates/contract/sui-template/src/dubhe/sources/codegen/init_test.move +8 -14
  61. package/templates/contract/sui-template/src/dubhe/sources/core/account_key.move +1 -3
  62. package/templates/contract/sui-template/src/dubhe/sources/core/dapp_service.move +1776 -137
  63. package/templates/contract/sui-template/src/dubhe/sources/core/data_key.move +1 -20
  64. package/templates/contract/sui-template/src/dubhe/sources/core/events.move +864 -25
  65. package/templates/contract/sui-template/src/dubhe/sources/scripts/deploy_hook.move +15 -16
  66. package/templates/contract/sui-template/src/dubhe/sources/scripts/migrate.move +0 -3
  67. package/templates/contract/sui-template/src/dubhe/sources/systems/address_system.move +25 -17
  68. package/templates/contract/sui-template/src/dubhe/sources/systems/dapp_system.move +2802 -343
  69. package/templates/contract/sui-template/src/dubhe/sources/systems/utils.move +1 -1
  70. package/templates/contract/sui-template/src/dubhe/sources/tests/address.move +173 -55
  71. package/templates/contract/sui-template/src/dubhe/sources/tests/dapp_test.move +769 -0
  72. package/templates/contract/sui-template/src/dubhe/sources/tests/fee_test.move +2965 -0
  73. package/templates/contract/sui-template/src/dubhe/sources/tests/integration_test.move +303 -0
  74. package/templates/contract/sui-template/src/dubhe/sources/tests/listing_test.move +1422 -0
  75. package/templates/contract/sui-template/src/dubhe/sources/tests/scene_session_test.move +269 -0
  76. package/templates/contract/sui-template/src/dubhe/sources/tests/session_test.move +624 -0
  77. package/templates/contract/sui-template/src/dubhe/sources/tests/storage_test.move +700 -0
  78. package/templates/contract/sui-template/src/dubhe/sources/tests/typed_object_test.move +177 -0
  79. package/templates/contract/sui-template/src/dubhe/sources/tests/typed_scene_test.move +452 -0
  80. package/templates/contract/sui-template/src/dubhe/sources/tests/user_storage_test.move +160 -0
  81. package/templates/contract/sui-template/src/dubhe/sources/utils/math.move +4 -3
  82. package/templates/contract/sui-template/src/dubhe/sources/utils/type_info.move +2 -2
  83. package/templates/contract/sui-template/src/template/Move.toml +12 -0
  84. package/templates/contract/sui-template/src/template/sources/codegen/dapp_key.move +47 -0
  85. package/templates/contract/sui-template/src/template/sources/codegen/genesis.move +34 -0
  86. package/templates/contract/sui-template/src/template/sources/codegen/init_test.move +23 -0
  87. package/templates/contract/sui-template/src/template/sources/codegen/user_storage_init.move +27 -0
  88. package/templates/contract/sui-template/src/template/sources/scripts/deploy_hook.move +13 -0
  89. package/templates/contract/sui-template/src/template/sources/scripts/migrate.move +7 -0
  90. package/templates/nextjs/sui-card-duel/.gitignore_ +51 -0
  91. package/templates/nextjs/sui-card-duel/README.md +213 -0
  92. package/templates/nextjs/sui-card-duel/docker-compose.yml +34 -0
  93. package/templates/nextjs/sui-card-duel/mprocs.yaml +17 -0
  94. package/templates/nextjs/sui-card-duel/package.json +43 -0
  95. package/templates/nextjs/sui-card-duel/packages/client/.gitignore_ +48 -0
  96. package/templates/nextjs/sui-card-duel/packages/client/.prettierignore +1 -0
  97. package/templates/nextjs/sui-card-duel/packages/client/.prettierrc.json +8 -0
  98. package/templates/nextjs/sui-card-duel/packages/client/eslint.config.mjs +22 -0
  99. package/templates/nextjs/sui-card-duel/packages/client/next.config.mjs +8 -0
  100. package/templates/nextjs/sui-card-duel/packages/client/package.json +47 -0
  101. package/templates/nextjs/sui-card-duel/packages/client/postcss.config.mjs +8 -0
  102. package/templates/nextjs/sui-card-duel/packages/client/src/app/admin/ArenaPanel.tsx +307 -0
  103. package/templates/nextjs/sui-card-duel/packages/client/src/app/admin/page.tsx +622 -0
  104. package/templates/nextjs/sui-card-duel/packages/client/src/app/brawl/[id]/page.tsx +559 -0
  105. package/templates/nextjs/sui-card-duel/packages/client/src/app/collection/page.tsx +202 -0
  106. package/templates/nextjs/sui-card-duel/packages/client/src/app/components/CardView.tsx +66 -0
  107. package/templates/nextjs/sui-card-duel/packages/client/src/app/components/GameShell.tsx +294 -0
  108. package/templates/nextjs/sui-card-duel/packages/client/src/app/components/icons.tsx +101 -0
  109. package/templates/nextjs/sui-card-duel/packages/client/src/app/duel/[id]/page.tsx +477 -0
  110. package/templates/nextjs/sui-card-duel/packages/client/src/app/favicon.ico +0 -0
  111. package/templates/nextjs/sui-card-duel/packages/client/src/app/globals.css +85 -0
  112. package/templates/nextjs/sui-card-duel/packages/client/src/app/hooks/useGame.ts +313 -0
  113. package/templates/nextjs/sui-card-duel/packages/client/src/app/layout.tsx +24 -0
  114. package/templates/nextjs/sui-card-duel/packages/client/src/app/leaderboard/page.tsx +123 -0
  115. package/templates/nextjs/sui-card-duel/packages/client/src/app/lib/game.ts +77 -0
  116. package/templates/nextjs/sui-card-duel/packages/client/src/app/lib/scenes.ts +226 -0
  117. package/templates/nextjs/sui-card-duel/packages/client/src/app/market/page.tsx +418 -0
  118. package/templates/nextjs/sui-card-duel/packages/client/src/app/page.tsx +427 -0
  119. package/templates/nextjs/sui-card-duel/packages/client/src/app/providers.tsx +69 -0
  120. package/templates/nextjs/sui-card-duel/packages/client/tailwind.config.ts +21 -0
  121. package/templates/nextjs/sui-card-duel/packages/client/tsconfig.json +30 -0
  122. package/templates/nextjs/sui-card-duel/packages/contracts/.gitignore_ +51 -0
  123. package/templates/nextjs/sui-card-duel/packages/contracts/.prettierignore +1 -0
  124. package/templates/nextjs/sui-card-duel/packages/contracts/.prettierrc.json +8 -0
  125. package/templates/nextjs/sui-card-duel/packages/contracts/Dockerfile +5 -0
  126. package/templates/nextjs/sui-card-duel/packages/contracts/Pub.localnet.toml +13 -0
  127. package/templates/nextjs/sui-card-duel/packages/contracts/card_duel.lock.json +66 -0
  128. package/templates/nextjs/sui-card-duel/packages/contracts/docker-compose.yml +34 -0
  129. package/templates/nextjs/sui-card-duel/packages/contracts/dubhe.config.ts +150 -0
  130. package/templates/nextjs/sui-card-duel/packages/contracts/logs/combined.log +31383 -0
  131. package/templates/nextjs/sui-card-duel/packages/contracts/package.json +49 -0
  132. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/config.ts +17 -0
  133. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/e2e-brawl.ts +270 -0
  134. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/e2e-duel.ts +272 -0
  135. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/e2e-lobby.ts +177 -0
  136. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/e2e-market.ts +219 -0
  137. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/e2e-session.ts +342 -0
  138. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/query-dapp-revenue.ts +95 -0
  139. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/seed.ts +92 -0
  140. package/templates/nextjs/sui-card-duel/packages/contracts/scripts/withdraw-dapp-revenue.ts +56 -0
  141. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/Move.toml +15 -0
  142. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/dapp_key.move +46 -0
  143. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/enums/card_kind.move +47 -0
  144. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/enums/match_state.move +37 -0
  145. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/enums/rarity.move +37 -0
  146. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/error.move +126 -0
  147. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/genesis.move +33 -0
  148. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/init_test.move +23 -0
  149. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/objects/arena.move +137 -0
  150. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/permits/brawl_permit.move +125 -0
  151. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/permits/duel_permit.move +125 -0
  152. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/battle_state.move +255 -0
  153. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/card.move +282 -0
  154. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/deck.move +64 -0
  155. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/game_config.move +267 -0
  156. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/gold.move +205 -0
  157. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/resources/profile.move +255 -0
  158. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/scenes/brawl.move +313 -0
  159. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/scenes/duel.move +313 -0
  160. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/codegen/user_storage_init.move +26 -0
  161. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/scripts/deploy_hook.move +32 -0
  162. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/scripts/migrate.move +7 -0
  163. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/arena_system.move +57 -0
  164. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/brawl_system.move +559 -0
  165. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/card_system.move +146 -0
  166. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/duel_system.move +515 -0
  167. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/market_system.move +115 -0
  168. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/systems/player_system.move +37 -0
  169. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/tests/brawl_tests.move +385 -0
  170. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/tests/duel_tests.move +656 -0
  171. package/templates/nextjs/sui-card-duel/packages/contracts/src/card_duel/sources/tests/test_helpers.move +31 -0
  172. package/templates/nextjs/sui-card-duel/packages/contracts/sui-indexer-schema.graphql +5973 -0
  173. package/templates/nextjs/sui-card-duel/pnpm-workspace.yaml +2 -0
  174. package/templates/nextjs/sui-farm/.gitignore_ +51 -0
  175. package/templates/nextjs/sui-farm/README.md +15 -0
  176. package/templates/nextjs/sui-farm/UPGRADE_NOTES.md +97 -0
  177. package/templates/nextjs/sui-farm/docker-compose.yml +34 -0
  178. package/templates/nextjs/sui-farm/mprocs.yaml +17 -0
  179. package/templates/nextjs/sui-farm/package.json +43 -0
  180. package/templates/nextjs/sui-farm/packages/client/.gitignore_ +48 -0
  181. package/templates/nextjs/sui-farm/packages/client/.prettierignore +1 -0
  182. package/templates/nextjs/sui-farm/packages/client/.prettierrc.json +8 -0
  183. package/templates/nextjs/sui-farm/packages/client/eslint.config.mjs +22 -0
  184. package/templates/nextjs/sui-farm/packages/client/next.config.mjs +8 -0
  185. package/templates/nextjs/sui-farm/packages/client/package.json +47 -0
  186. package/templates/nextjs/sui-farm/packages/client/postcss.config.mjs +8 -0
  187. package/templates/nextjs/sui-farm/packages/client/src/app/admin/page.tsx +618 -0
  188. package/templates/nextjs/sui-farm/packages/client/src/app/components/FarmLand.tsx +526 -0
  189. package/templates/nextjs/sui-farm/packages/client/src/app/components/FarmPlotCard.tsx +215 -0
  190. package/templates/nextjs/sui-farm/packages/client/src/app/components/PetAvatar.tsx +868 -0
  191. package/templates/nextjs/sui-farm/packages/client/src/app/components/PetPanel.tsx +1360 -0
  192. package/templates/nextjs/sui-farm/packages/client/src/app/components/PlantModal.tsx +147 -0
  193. package/templates/nextjs/sui-farm/packages/client/src/app/components/ProxyCard.tsx +684 -0
  194. package/templates/nextjs/sui-farm/packages/client/src/app/components/RanchLand.tsx +822 -0
  195. package/templates/nextjs/sui-farm/packages/client/src/app/components/ResourceHUD.tsx +125 -0
  196. package/templates/nextjs/sui-farm/packages/client/src/app/components/ShopPanel.tsx +232 -0
  197. package/templates/nextjs/sui-farm/packages/client/src/app/components/icons/GameIcons.tsx +574 -0
  198. package/templates/nextjs/sui-farm/packages/client/src/app/favicon.ico +0 -0
  199. package/templates/nextjs/sui-farm/packages/client/src/app/globals.css +423 -0
  200. package/templates/nextjs/sui-farm/packages/client/src/app/hooks/useWorldPermitId.ts +66 -0
  201. package/templates/nextjs/sui-farm/packages/client/src/app/layout.tsx +23 -0
  202. package/templates/nextjs/sui-farm/packages/client/src/app/leaderboard/page.tsx +185 -0
  203. package/templates/nextjs/sui-farm/packages/client/src/app/lib/crops.ts +97 -0
  204. package/templates/nextjs/sui-farm/packages/client/src/app/market/page.tsx +763 -0
  205. package/templates/nextjs/sui-farm/packages/client/src/app/page.tsx +1173 -0
  206. package/templates/nextjs/sui-farm/packages/client/src/app/providers.tsx +69 -0
  207. package/templates/nextjs/sui-farm/packages/client/src/app/state/index.tsx +5 -0
  208. package/templates/nextjs/sui-farm/packages/client/tailwind.config.ts +25 -0
  209. package/templates/nextjs/sui-farm/packages/client/tsconfig.json +30 -0
  210. package/templates/nextjs/sui-farm/packages/contracts/.gitignore_ +51 -0
  211. package/templates/nextjs/sui-farm/packages/contracts/.prettierignore +1 -0
  212. package/templates/nextjs/sui-farm/packages/contracts/.prettierrc.json +8 -0
  213. package/templates/nextjs/sui-farm/packages/contracts/Dockerfile +5 -0
  214. package/templates/nextjs/sui-farm/packages/contracts/Pub.localnet.toml +13 -0
  215. package/templates/nextjs/sui-farm/packages/contracts/counter.lock.json +14 -0
  216. package/templates/nextjs/sui-farm/packages/contracts/docker-compose.yml +34 -0
  217. package/templates/nextjs/sui-farm/packages/contracts/dubhe.config.ts +178 -0
  218. package/templates/nextjs/sui-farm/packages/contracts/harvest.lock.json +120 -0
  219. package/templates/nextjs/sui-farm/packages/contracts/package.json +48 -0
  220. package/templates/nextjs/sui-farm/packages/contracts/scripts/config.ts +17 -0
  221. package/templates/nextjs/sui-farm/packages/contracts/scripts/query-dapp-revenue.ts +95 -0
  222. package/templates/nextjs/sui-farm/packages/contracts/scripts/read-permit.ts +72 -0
  223. package/templates/nextjs/sui-farm/packages/contracts/scripts/seed.ts +85 -0
  224. package/templates/nextjs/sui-farm/packages/contracts/scripts/withdraw-dapp-revenue.ts +56 -0
  225. package/templates/nextjs/sui-farm/packages/contracts/src/counter/Move.toml +14 -0
  226. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/dapp_key.move +31 -0
  227. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/error.move +10 -0
  228. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/genesis.move +33 -0
  229. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/init_test.move +23 -0
  230. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/resources/counter1.move +64 -0
  231. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/resources/counter2.move +70 -0
  232. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/user_storage_init.move +26 -0
  233. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/scripts/deploy_hook.move +8 -0
  234. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/scripts/migrate.move +8 -0
  235. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/systems/counter.move +13 -0
  236. package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/tests/counter.move +28 -0
  237. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/Move.toml +14 -0
  238. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/dapp_key.move +46 -0
  239. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/enums/crop_type.move +47 -0
  240. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/enums/egg_type.move +42 -0
  241. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/enums/pet_rarity.move +37 -0
  242. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/enums/pet_species.move +52 -0
  243. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/error.move +110 -0
  244. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/genesis.move +33 -0
  245. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/init_test.move +23 -0
  246. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/permits/world.move +125 -0
  247. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/carrot.move +136 -0
  248. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/carrot_seed.move +80 -0
  249. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/common_egg.move +136 -0
  250. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/corn.move +136 -0
  251. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/corn_seed.move +80 -0
  252. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/crow_charges.move +162 -0
  253. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/crow_damage.move +207 -0
  254. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/farm_plot.move +261 -0
  255. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/gold.move +80 -0
  256. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pet.move +467 -0
  257. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pet_config.move +372 -0
  258. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pet_hatch.move +162 -0
  259. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pet_slot_index.move +83 -0
  260. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pet_slots.move +64 -0
  261. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/profile.move +162 -0
  262. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pumpkin.move +136 -0
  263. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/pumpkin_seed.move +80 -0
  264. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/rare_egg.move +136 -0
  265. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/scarecrow.move +64 -0
  266. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/season_config.move +197 -0
  267. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/season_stats.move +64 -0
  268. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/seasonal_egg.move +136 -0
  269. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/shop_config.move +267 -0
  270. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/trophy.move +245 -0
  271. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/wheat.move +136 -0
  272. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/wheat_seed.move +80 -0
  273. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/world_permit_id.move +64 -0
  274. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/user_storage_init.move +26 -0
  275. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/scripts/deploy_hook.move +45 -0
  276. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/scripts/migrate.move +7 -0
  277. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/crow_system.move +96 -0
  278. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/farm_system.move +182 -0
  279. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/market_system.move +172 -0
  280. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/pet_system.move +495 -0
  281. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/season_system.move +70 -0
  282. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/shop_system.move +112 -0
  283. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/world_system.move +34 -0
  284. package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/tests/farm_tests.move +1192 -0
  285. package/templates/nextjs/sui-farm/pnpm-workspace.yaml +2 -0
  286. package/templates/nextjs/sui-template/packages/client/src/app/components/ProxyCard.tsx +683 -0
  287. package/templates/nextjs/sui-template/packages/client/src/app/page.tsx +510 -5
  288. package/templates/nextjs/sui-template/packages/client/src/app/providers.tsx +13 -5
  289. package/templates/nextjs/sui-template/packages/contracts/Pub.localnet.toml +4 -4
  290. package/templates/nextjs/sui-template/packages/contracts/counter.lock.json +14 -0
  291. package/templates/nextjs/sui-template/packages/contracts/deployment.ts +8 -3
  292. package/templates/nextjs/sui-template/packages/contracts/dubhe.config.json +9 -9
  293. package/templates/nextjs/sui-template/packages/contracts/dubhe.config.ts +0 -4
  294. package/templates/nextjs/sui-template/packages/contracts/metadata.json +180 -124
  295. package/templates/nextjs/sui-template/packages/contracts/package.json +8 -4
  296. package/templates/nextjs/sui-template/packages/contracts/src/counter/Move.toml +4 -0
  297. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/dapp_key.move +45 -31
  298. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/error.move +10 -0
  299. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/genesis.move +30 -13
  300. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/init_test.move +19 -14
  301. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter1.move +30 -20
  302. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter2.move +35 -24
  303. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/user_storage_init.move +26 -0
  304. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/scripts/deploy_hook.move +6 -10
  305. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/systems/counter.move +7 -20
  306. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/tests/counter.move +14 -27
  307. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.lock +33 -30
  308. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.toml +8 -3
  309. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move +45 -31
  310. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/error.move +170 -0
  311. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/genesis.move +16 -13
  312. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/init_test.move +8 -14
  313. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/account_key.move +1 -3
  314. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move +1776 -137
  315. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/data_key.move +1 -20
  316. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/events.move +864 -25
  317. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/scripts/deploy_hook.move +15 -16
  318. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/scripts/migrate.move +0 -3
  319. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/address_system.move +25 -17
  320. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +2802 -343
  321. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/utils.move +1 -1
  322. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/address.move +173 -55
  323. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/dapp_test.move +769 -0
  324. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +2965 -0
  325. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move +303 -0
  326. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/listing_test.move +1422 -0
  327. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/scene_session_test.move +269 -0
  328. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/session_test.move +624 -0
  329. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/storage_test.move +700 -0
  330. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_object_test.move +177 -0
  331. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_scene_test.move +452 -0
  332. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/user_storage_test.move +160 -0
  333. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/utils/math.move +4 -3
  334. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/utils/type_info.move +2 -2
  335. package/templates/101/sui-template/packages/contracts/src/counter/Move.lock +0 -41
  336. package/templates/101/sui-template/packages/contracts/src/counter/Published.toml +0 -9
  337. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/errors.move +0 -12
  338. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/errors.move +0 -140
  339. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  340. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  341. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  342. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  343. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/dapp_store.move +0 -29
  344. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/session_system.move +0 -44
  345. package/templates/contract/sui-template/src/dubhe/sources/codegen/errors.move +0 -140
  346. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  347. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  348. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  349. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  350. package/templates/contract/sui-template/src/dubhe/sources/core/dapp_store.move +0 -29
  351. package/templates/contract/sui-template/src/dubhe/sources/systems/session_system.move +0 -44
  352. package/templates/nextjs/sui-template/packages/contracts/src/counter/Move.lock +0 -47
  353. package/templates/nextjs/sui-template/packages/contracts/src/counter/Published.toml +0 -9
  354. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/errors.move +0 -12
  355. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/errors.move +0 -140
  356. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  357. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  358. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  359. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  360. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/dapp_store.move +0 -29
  361. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/session_system.move +0 -44
@@ -0,0 +1,700 @@
1
+ /// Unit tests — Storage read/write operations
2
+ ///
3
+ /// Covers UserStorage and DappStorage record/field operations:
4
+ /// set_record, set_field, delete_record, delete_field (UserStorage)
5
+ /// set_global_record, set_global_field, delete_global_record, delete_global_field (DappStorage)
6
+ /// Read helpers: has_record, get_field, ensure_has_record, ensure_has_not_record
7
+ /// Error guards: dapp_key_mismatch, write_authorization, write_limit
8
+ /// Error guards: ELengthMismatch (field_names/values length mismatch, user + global)
9
+ /// Error guards: EInvalidKey (set_field / set_global_field on non-existent record)
10
+ ///
11
+ /// Design: every test uses sui::tx_context::dummy() — no test_scenario needed.
12
+ /// Authorization tests use a UserStorage owned by @0xDEAD so ctx.sender() ≠ owner.
13
+ /// DappKey-mismatch tests use ctx.sender() as owner so only the key check fires.
14
+ #[test_only]
15
+ module dubhe::storage_test;
16
+
17
+ use dubhe::dapp_service::{Self, UserStorage, DappStorage, DappHub};
18
+ use dubhe::dapp_system;
19
+ use sui::bcs;
20
+ use sui::bcs::to_bytes;
21
+
22
+ // Two distinct DApp key types used to trigger dapp_key_mismatch.
23
+ public struct StoreKey has copy, drop {}
24
+ public struct WrongKey has copy, drop {}
25
+
26
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
27
+
28
+ fun k(name: vector<u8>): vector<vector<u8>> { vector[name] }
29
+ fun fns(): vector<vector<u8>> { vector[b"v"] }
30
+ fun u32_val(v: u32): vector<vector<u8>> { vector[to_bytes(&v)] }
31
+
32
+ // Free-tier DappHub (fee=0) — used by most tests so global writes need no credit.
33
+ fun make_dh(ctx: &mut TxContext): DappHub {
34
+ dapp_service::create_free_dapp_hub_for_testing(ctx)
35
+ }
36
+
37
+ // UserStorage owned by ctx.sender() — auth check passes.
38
+ fun us_owned(ctx: &mut TxContext): UserStorage {
39
+ dapp_service::create_user_storage_for_testing<StoreKey>(ctx.sender(), ctx)
40
+ }
41
+
42
+ // UserStorage owned by a foreign address — auth check fails.
43
+ fun us_foreign(ctx: &mut TxContext): UserStorage {
44
+ dapp_service::create_user_storage_for_testing<StoreKey>(@0xDEAD, ctx)
45
+ }
46
+
47
+ // UserStorage with StoreKey but owned by ctx.sender() — used for key-mismatch tests.
48
+ fun us_for_mismatch(ctx: &mut TxContext): UserStorage {
49
+ dapp_service::create_user_storage_for_testing<StoreKey>(ctx.sender(), ctx)
50
+ }
51
+
52
+ fun ds(ctx: &mut TxContext): DappStorage {
53
+ dapp_service::create_dapp_storage_for_testing<StoreKey>(ctx)
54
+ }
55
+
56
+ // ═══════════════════════════════════════════════════════════════════════════════
57
+ // UserStorage — set_record
58
+ // ═══════════════════════════════════════════════════════════════════════════════
59
+
60
+ #[test]
61
+ fun test_set_record_creates_record() {
62
+ let mut ctx = sui::tx_context::dummy();
63
+ let dh = make_dh(&mut ctx);
64
+ let mut us = us_owned(&mut ctx);
65
+
66
+ assert!(!dapp_system::has_record<StoreKey>(&us, k(b"hp")));
67
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(100), false, &mut ctx);
68
+ assert!(dapp_system::has_record<StoreKey>(&us, k(b"hp")));
69
+
70
+ dapp_service::destroy_user_storage(us);
71
+ dapp_service::destroy_dapp_hub(dh);
72
+ }
73
+
74
+ #[test]
75
+ fun test_set_record_overwrites_existing_value() {
76
+ let mut ctx = sui::tx_context::dummy();
77
+ let dh = make_dh(&mut ctx);
78
+ let mut us = us_owned(&mut ctx);
79
+
80
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(50), false, &mut ctx);
81
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(99), false, &mut ctx);
82
+
83
+ let raw = dapp_system::get_field<StoreKey>(&us, k(b"hp"), b"v");
84
+ let mut b = bcs::new(raw);
85
+ assert!(bcs::peel_u32(&mut b) == 99);
86
+
87
+ dapp_service::destroy_user_storage(us);
88
+ dapp_service::destroy_dapp_hub(dh);
89
+ }
90
+
91
+ #[test]
92
+ fun test_set_record_increments_write_count() {
93
+ let mut ctx = sui::tx_context::dummy();
94
+ let dh = make_dh(&mut ctx);
95
+ let mut us = us_owned(&mut ctx);
96
+
97
+ assert!(dapp_service::write_count(&us) == 0);
98
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"a"), fns(), u32_val(1), false, &mut ctx);
99
+ assert!(dapp_service::write_count(&us) == 1);
100
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"b"), fns(), u32_val(2), false, &mut ctx);
101
+ assert!(dapp_service::write_count(&us) == 2);
102
+
103
+ dapp_service::destroy_user_storage(us);
104
+ dapp_service::destroy_dapp_hub(dh);
105
+ }
106
+
107
+ #[test]
108
+ fun test_set_record_offchain_increments_write_count_but_not_bytes() {
109
+ let mut ctx = sui::tx_context::dummy();
110
+ let dh = make_dh(&mut ctx);
111
+ let mut us = us_owned(&mut ctx);
112
+
113
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"x"), fns(), u32_val(7), true, &mut ctx);
114
+
115
+ // Off-chain writes emit an event but do NOT store data on-chain.
116
+ // write_count is still incremented (the framework was used); write_bytes stays 0.
117
+ assert!(dapp_service::write_count(&us) == 1);
118
+ assert!(dapp_service::write_bytes(&us) == 0);
119
+ assert!(!dapp_system::has_record<StoreKey>(&us, k(b"x")));
120
+
121
+ dapp_service::destroy_user_storage(us);
122
+ dapp_service::destroy_dapp_hub(dh);
123
+ }
124
+
125
+ #[test]
126
+ #[expected_failure]
127
+ fun test_set_record_aborts_on_dapp_key_mismatch() {
128
+ let mut ctx = sui::tx_context::dummy();
129
+ let dh = make_dh(&mut ctx);
130
+ let mut us = us_for_mismatch(&mut ctx);
131
+ // WrongKey does not match UserStorage's StoreKey → dapp_key_mismatch
132
+ dapp_system::set_record<WrongKey>(WrongKey {}, &mut us, k(b"x"), fns(), u32_val(1), false, &mut ctx);
133
+ dapp_service::destroy_user_storage(us);
134
+ dapp_service::destroy_dapp_hub(dh);
135
+ }
136
+
137
+ #[test]
138
+ #[expected_failure]
139
+ fun test_set_record_aborts_when_not_authorized() {
140
+ let mut ctx = sui::tx_context::dummy();
141
+ let dh = make_dh(&mut ctx);
142
+ // canonical_owner = @0xDEAD ≠ ctx.sender() → no_permission
143
+ let mut us = us_foreign(&mut ctx);
144
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"x"), fns(), u32_val(1), false, &mut ctx);
145
+ dapp_service::destroy_user_storage(us);
146
+ dapp_service::destroy_dapp_hub(dh);
147
+ }
148
+
149
+ #[test]
150
+ #[expected_failure]
151
+ fun test_set_record_aborts_at_write_limit() {
152
+ let mut ctx = sui::tx_context::dummy();
153
+ let dh = make_dh(&mut ctx);
154
+ let mut us = us_owned(&mut ctx);
155
+
156
+ // MAX_UNSETTLED_WRITES = 1000: fill exactly to the limit.
157
+ let max_writes = 1000u64;
158
+ let mut i = 0u64;
159
+ while (i < max_writes) {
160
+ dapp_service::increment_write_count(&mut us);
161
+ i = i + 1;
162
+ };
163
+
164
+ // One write over the limit must abort.
165
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"over"), fns(), u32_val(0), false, &mut ctx);
166
+ dapp_service::destroy_user_storage(us);
167
+ dapp_service::destroy_dapp_hub(dh);
168
+ }
169
+
170
+ // ═══════════════════════════════════════════════════════════════════════════════
171
+ // UserStorage — set_field
172
+ // ═══════════════════════════════════════════════════════════════════════════════
173
+
174
+ #[test]
175
+ fun test_set_field_updates_single_field() {
176
+ let mut ctx = sui::tx_context::dummy();
177
+ let dh = make_dh(&mut ctx);
178
+ let mut us = us_owned(&mut ctx);
179
+
180
+ // Write a record with two fields.
181
+ dapp_system::set_record<StoreKey>(
182
+ StoreKey {}, &mut us, k(b"p"),
183
+ vector[b"hp", b"mp"],
184
+ vector[to_bytes(&10u32), to_bytes(&20u32)],
185
+ false, &mut ctx
186
+ );
187
+
188
+ // Update only "hp".
189
+ dapp_system::set_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"hp", to_bytes(&99u32), &mut ctx);
190
+
191
+ let raw_hp = dapp_system::get_field<StoreKey>(&us, k(b"p"), b"hp");
192
+ let mut b = bcs::new(raw_hp);
193
+ assert!(bcs::peel_u32(&mut b) == 99);
194
+
195
+ // "mp" must remain unchanged.
196
+ let raw_mp = dapp_system::get_field<StoreKey>(&us, k(b"p"), b"mp");
197
+ let mut b2 = bcs::new(raw_mp);
198
+ assert!(bcs::peel_u32(&mut b2) == 20);
199
+
200
+ dapp_service::destroy_user_storage(us);
201
+ dapp_service::destroy_dapp_hub(dh);
202
+ }
203
+
204
+ #[test]
205
+ fun test_set_field_increments_write_count() {
206
+ let mut ctx = sui::tx_context::dummy();
207
+ let dh = make_dh(&mut ctx);
208
+ let mut us = us_owned(&mut ctx);
209
+
210
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"p"), fns(), u32_val(1), false, &mut ctx);
211
+ let before = dapp_service::write_count(&us);
212
+
213
+ dapp_system::set_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"v", to_bytes(&2u32), &mut ctx);
214
+ assert!(dapp_service::write_count(&us) == before + 1);
215
+
216
+ dapp_service::destroy_user_storage(us);
217
+ dapp_service::destroy_dapp_hub(dh);
218
+ }
219
+
220
+ #[test]
221
+ #[expected_failure]
222
+ fun test_set_field_aborts_on_dapp_key_mismatch() {
223
+ let mut ctx = sui::tx_context::dummy();
224
+ let dh = make_dh(&mut ctx);
225
+ let mut us = us_for_mismatch(&mut ctx);
226
+ dapp_system::set_field<WrongKey>(WrongKey {}, &mut us, k(b"p"), b"v", to_bytes(&1u32), &mut ctx);
227
+ dapp_service::destroy_user_storage(us);
228
+ dapp_service::destroy_dapp_hub(dh);
229
+ }
230
+
231
+ #[test]
232
+ #[expected_failure]
233
+ fun test_set_field_aborts_when_not_authorized() {
234
+ let mut ctx = sui::tx_context::dummy();
235
+ let dh = make_dh(&mut ctx);
236
+ let mut us = us_foreign(&mut ctx);
237
+ dapp_system::set_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"v", to_bytes(&1u32), &mut ctx);
238
+ dapp_service::destroy_user_storage(us);
239
+ dapp_service::destroy_dapp_hub(dh);
240
+ }
241
+
242
+ // ═══════════════════════════════════════════════════════════════════════════════
243
+ // UserStorage — delete_record
244
+ // ═══════════════════════════════════════════════════════════════════════════════
245
+
246
+ #[test]
247
+ fun test_delete_record_removes_record() {
248
+ let mut ctx = sui::tx_context::dummy();
249
+ let dh = make_dh(&mut ctx);
250
+ let mut us = us_owned(&mut ctx);
251
+
252
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(100), false, &mut ctx);
253
+ assert!(dapp_system::has_record<StoreKey>(&us, k(b"hp")));
254
+
255
+ dapp_system::delete_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), &ctx);
256
+ assert!(!dapp_system::has_record<StoreKey>(&us, k(b"hp")));
257
+
258
+ dapp_service::destroy_user_storage(us);
259
+ dapp_service::destroy_dapp_hub(dh);
260
+ }
261
+
262
+ #[test]
263
+ fun test_delete_record_does_not_increment_write_count() {
264
+ let mut ctx = sui::tx_context::dummy();
265
+ let dh = make_dh(&mut ctx);
266
+ let mut us = us_owned(&mut ctx);
267
+
268
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(1), false, &mut ctx);
269
+ let count_after_write = dapp_service::write_count(&us);
270
+
271
+ dapp_system::delete_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), &ctx);
272
+ assert!(dapp_service::write_count(&us) == count_after_write);
273
+
274
+ dapp_service::destroy_user_storage(us);
275
+ dapp_service::destroy_dapp_hub(dh);
276
+ }
277
+
278
+ #[test]
279
+ #[expected_failure]
280
+ fun test_delete_record_aborts_on_dapp_key_mismatch() {
281
+ let mut ctx = sui::tx_context::dummy();
282
+ let dh = make_dh(&mut ctx);
283
+ let mut us = us_for_mismatch(&mut ctx);
284
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(1), false, &mut ctx);
285
+ dapp_system::delete_record<WrongKey>(WrongKey {}, &mut us, k(b"hp"), fns(), &ctx);
286
+ dapp_service::destroy_user_storage(us);
287
+ dapp_service::destroy_dapp_hub(dh);
288
+ }
289
+
290
+ #[test]
291
+ #[expected_failure]
292
+ fun test_delete_record_aborts_when_not_authorized() {
293
+ let mut ctx = sui::tx_context::dummy();
294
+ let mut us = us_foreign(&mut ctx);
295
+ dapp_system::delete_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), &ctx);
296
+ dapp_service::destroy_user_storage(us);
297
+ }
298
+
299
+ // ═══════════════════════════════════════════════════════════════════════════════
300
+ // UserStorage — delete_field
301
+ // ═══════════════════════════════════════════════════════════════════════════════
302
+
303
+ #[test]
304
+ fun test_delete_field_removes_only_target_field() {
305
+ let mut ctx = sui::tx_context::dummy();
306
+ let dh = make_dh(&mut ctx);
307
+ let mut us = us_owned(&mut ctx);
308
+
309
+ dapp_system::set_record<StoreKey>(
310
+ StoreKey {}, &mut us, k(b"p"),
311
+ vector[b"hp", b"mp"],
312
+ vector[to_bytes(&1u32), to_bytes(&2u32)],
313
+ false, &mut ctx
314
+ );
315
+
316
+ dapp_system::delete_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"hp", &ctx);
317
+
318
+ // "mp" must still be accessible.
319
+ let raw = dapp_system::get_field<StoreKey>(&us, k(b"p"), b"mp");
320
+ let mut b = bcs::new(raw);
321
+ assert!(bcs::peel_u32(&mut b) == 2);
322
+
323
+ dapp_service::destroy_user_storage(us);
324
+ dapp_service::destroy_dapp_hub(dh);
325
+ }
326
+
327
+ #[test]
328
+ #[expected_failure]
329
+ fun test_delete_field_aborts_on_dapp_key_mismatch() {
330
+ let mut ctx = sui::tx_context::dummy();
331
+ let mut us = us_for_mismatch(&mut ctx);
332
+ dapp_system::delete_field<WrongKey>(WrongKey {}, &mut us, k(b"p"), b"v", &ctx);
333
+ dapp_service::destroy_user_storage(us);
334
+ }
335
+
336
+ #[test]
337
+ #[expected_failure]
338
+ fun test_delete_field_aborts_when_not_authorized() {
339
+ let mut ctx = sui::tx_context::dummy();
340
+ let mut us = us_foreign(&mut ctx);
341
+ dapp_system::delete_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"v", &ctx);
342
+ dapp_service::destroy_user_storage(us);
343
+ }
344
+
345
+ // ═══════════════════════════════════════════════════════════════════════════════
346
+ // UserStorage — read helpers
347
+ // ═══════════════════════════════════════════════════════════════════════════════
348
+
349
+ #[test]
350
+ fun test_has_record_false_before_write_true_after() {
351
+ let mut ctx = sui::tx_context::dummy();
352
+ let dh = make_dh(&mut ctx);
353
+ let mut us = us_owned(&mut ctx);
354
+
355
+ assert!(!dapp_system::has_record<StoreKey>(&us, k(b"hp")));
356
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(1), false, &mut ctx);
357
+ assert!(dapp_system::has_record<StoreKey>(&us, k(b"hp")));
358
+
359
+ dapp_service::destroy_user_storage(us);
360
+ dapp_service::destroy_dapp_hub(dh);
361
+ }
362
+
363
+ #[test]
364
+ fun test_ensure_has_record_passes_when_exists() {
365
+ let mut ctx = sui::tx_context::dummy();
366
+ let dh = make_dh(&mut ctx);
367
+ let mut us = us_owned(&mut ctx);
368
+
369
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(1), false, &mut ctx);
370
+ dapp_system::ensure_has_record<StoreKey>(&us, k(b"hp"));
371
+
372
+ dapp_service::destroy_user_storage(us);
373
+ dapp_service::destroy_dapp_hub(dh);
374
+ }
375
+
376
+ #[test]
377
+ #[expected_failure]
378
+ fun test_ensure_has_record_aborts_when_missing() {
379
+ let mut ctx = sui::tx_context::dummy();
380
+ let us = us_owned(&mut ctx);
381
+ dapp_system::ensure_has_record<StoreKey>(&us, k(b"missing"));
382
+ dapp_service::destroy_user_storage(us);
383
+ }
384
+
385
+ #[test]
386
+ fun test_ensure_has_not_record_passes_when_missing() {
387
+ let mut ctx = sui::tx_context::dummy();
388
+ let us = us_owned(&mut ctx);
389
+ dapp_system::ensure_has_not_record<StoreKey>(&us, k(b"missing"));
390
+ dapp_service::destroy_user_storage(us);
391
+ }
392
+
393
+ #[test]
394
+ #[expected_failure]
395
+ fun test_ensure_has_not_record_aborts_when_exists() {
396
+ let mut ctx = sui::tx_context::dummy();
397
+ let dh = make_dh(&mut ctx);
398
+ let mut us = us_owned(&mut ctx);
399
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"hp"), fns(), u32_val(1), false, &mut ctx);
400
+ dapp_system::ensure_has_not_record<StoreKey>(&us, k(b"hp"));
401
+ dapp_service::destroy_user_storage(us);
402
+ dapp_service::destroy_dapp_hub(dh);
403
+ }
404
+
405
+ #[test]
406
+ fun test_get_field_returns_stored_value() {
407
+ let mut ctx = sui::tx_context::dummy();
408
+ let dh = make_dh(&mut ctx);
409
+ let mut us = us_owned(&mut ctx);
410
+
411
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"p"), fns(), u32_val(42), false, &mut ctx);
412
+
413
+ let raw = dapp_system::get_field<StoreKey>(&us, k(b"p"), b"v");
414
+ let mut b = bcs::new(raw);
415
+ assert!(bcs::peel_u32(&mut b) == 42);
416
+
417
+ dapp_service::destroy_user_storage(us);
418
+ dapp_service::destroy_dapp_hub(dh);
419
+ }
420
+
421
+ // ═══════════════════════════════════════════════════════════════════════════════
422
+ // DappStorage — global record/field operations
423
+ // ═══════════════════════════════════════════════════════════════════════════════
424
+
425
+ #[test]
426
+ fun test_set_global_record_creates_record() {
427
+ let mut ctx = sui::tx_context::dummy();
428
+ let dh = make_dh(&mut ctx);
429
+ let mut d = ds(&mut ctx);
430
+
431
+ assert!(!dapp_system::has_global_record<StoreKey>(&d, k(b"map")));
432
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"map"), fns(), u32_val(1), false);
433
+ assert!(dapp_system::has_global_record<StoreKey>(&d, k(b"map")));
434
+
435
+ dapp_service::destroy_dapp_storage(d);
436
+ dapp_service::destroy_dapp_hub(dh);
437
+ }
438
+
439
+ #[test]
440
+ fun test_set_global_record_overwrites_value() {
441
+ let mut ctx = sui::tx_context::dummy();
442
+ let dh = make_dh(&mut ctx);
443
+ let mut d = ds(&mut ctx);
444
+
445
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"cfg"), fns(), u32_val(1), false);
446
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"cfg"), fns(), u32_val(99), false);
447
+
448
+ let raw = dapp_system::get_global_field<StoreKey>(&d, k(b"cfg"), b"v");
449
+ let mut b = bcs::new(raw);
450
+ assert!(bcs::peel_u32(&mut b) == 99);
451
+
452
+ dapp_service::destroy_dapp_storage(d);
453
+ dapp_service::destroy_dapp_hub(dh);
454
+ }
455
+
456
+ #[test]
457
+ fun test_set_global_field_updates_field() {
458
+ let mut ctx = sui::tx_context::dummy();
459
+ let dh = make_dh(&mut ctx);
460
+ let mut d = ds(&mut ctx);
461
+
462
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"cfg"), fns(), u32_val(1), false);
463
+ dapp_system::set_global_field<StoreKey>(StoreKey {}, &mut d, k(b"cfg"), b"v", to_bytes(&77u32));
464
+
465
+ let raw = dapp_system::get_global_field<StoreKey>(&d, k(b"cfg"), b"v");
466
+ let mut b = bcs::new(raw);
467
+ assert!(bcs::peel_u32(&mut b) == 77);
468
+
469
+ dapp_service::destroy_dapp_storage(d);
470
+ dapp_service::destroy_dapp_hub(dh);
471
+ }
472
+
473
+ #[test]
474
+ fun test_delete_global_record_removes_record() {
475
+ let mut ctx = sui::tx_context::dummy();
476
+ let dh = make_dh(&mut ctx);
477
+ let mut d = ds(&mut ctx);
478
+
479
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"tmp"), fns(), u32_val(1), false);
480
+ assert!(dapp_system::has_global_record<StoreKey>(&d, k(b"tmp")));
481
+
482
+ dapp_system::delete_global_record<StoreKey>(StoreKey {}, &mut d, k(b"tmp"), fns());
483
+ assert!(!dapp_system::has_global_record<StoreKey>(&d, k(b"tmp")));
484
+
485
+ dapp_service::destroy_dapp_storage(d);
486
+ dapp_service::destroy_dapp_hub(dh);
487
+ }
488
+
489
+ #[test]
490
+ fun test_delete_global_field_removes_only_target_field() {
491
+ let mut ctx = sui::tx_context::dummy();
492
+ let dh = make_dh(&mut ctx);
493
+ let mut d = ds(&mut ctx);
494
+
495
+ dapp_system::set_global_record<StoreKey>(
496
+ StoreKey {}, &mut d, k(b"cfg"),
497
+ vector[b"a", b"b"],
498
+ vector[to_bytes(&1u32), to_bytes(&2u32)],
499
+ false
500
+ );
501
+ dapp_system::delete_global_field<StoreKey>(StoreKey {}, &mut d, k(b"cfg"), b"a");
502
+
503
+ let raw = dapp_system::get_global_field<StoreKey>(&d, k(b"cfg"), b"b");
504
+ let mut b = bcs::new(raw);
505
+ assert!(bcs::peel_u32(&mut b) == 2);
506
+
507
+ dapp_service::destroy_dapp_storage(d);
508
+ dapp_service::destroy_dapp_hub(dh);
509
+ }
510
+
511
+ #[test]
512
+ fun test_ensure_has_global_record_passes_when_exists() {
513
+ let mut ctx = sui::tx_context::dummy();
514
+ let dh = make_dh(&mut ctx);
515
+ let mut d = ds(&mut ctx);
516
+
517
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"g"), fns(), u32_val(1), false);
518
+ dapp_system::ensure_has_global_record<StoreKey>(&d, k(b"g"));
519
+
520
+ dapp_service::destroy_dapp_storage(d);
521
+ dapp_service::destroy_dapp_hub(dh);
522
+ }
523
+
524
+ #[test]
525
+ #[expected_failure]
526
+ fun test_ensure_has_global_record_aborts_when_missing() {
527
+ let mut ctx = sui::tx_context::dummy();
528
+ let d = ds(&mut ctx);
529
+ dapp_system::ensure_has_global_record<StoreKey>(&d, k(b"missing"));
530
+ dapp_service::destroy_dapp_storage(d);
531
+ }
532
+
533
+ #[test]
534
+ fun test_ensure_has_not_global_record_passes_when_missing() {
535
+ let mut ctx = sui::tx_context::dummy();
536
+ let d = ds(&mut ctx);
537
+ dapp_system::ensure_has_not_global_record<StoreKey>(&d, k(b"missing"));
538
+ dapp_service::destroy_dapp_storage(d);
539
+ }
540
+
541
+ #[test]
542
+ #[expected_failure]
543
+ fun test_ensure_has_not_global_record_aborts_when_exists() {
544
+ let mut ctx = sui::tx_context::dummy();
545
+ let dh = make_dh(&mut ctx);
546
+ let mut d = ds(&mut ctx);
547
+ dapp_system::set_global_record<StoreKey>(StoreKey {}, &mut d, k(b"g"), fns(), u32_val(1), false);
548
+ dapp_system::ensure_has_not_global_record<StoreKey>(&d, k(b"g"));
549
+ dapp_service::destroy_dapp_storage(d);
550
+ dapp_service::destroy_dapp_hub(dh);
551
+ }
552
+
553
+ #[test]
554
+ #[expected_failure]
555
+ fun test_set_global_record_aborts_on_dapp_key_mismatch() {
556
+ let mut ctx = sui::tx_context::dummy();
557
+ let dh = make_dh(&mut ctx);
558
+ // DappStorage keyed to StoreKey; write with WrongKey must abort.
559
+ let mut d = dapp_service::create_dapp_storage_for_testing<StoreKey>(&mut ctx);
560
+ dapp_system::set_global_record<WrongKey>(WrongKey {}, &mut d, k(b"x"), fns(), u32_val(1), false);
561
+ dapp_service::destroy_dapp_storage(d);
562
+ dapp_service::destroy_dapp_hub(dh);
563
+ }
564
+
565
+ #[test]
566
+ #[expected_failure]
567
+ fun test_set_global_field_aborts_on_dapp_key_mismatch() {
568
+ let mut ctx = sui::tx_context::dummy();
569
+ let dh = make_dh(&mut ctx);
570
+ let mut d = dapp_service::create_dapp_storage_for_testing<StoreKey>(&mut ctx);
571
+ dapp_system::set_global_field<WrongKey>(WrongKey {}, &mut d, k(b"x"), b"v", to_bytes(&1u32));
572
+ dapp_service::destroy_dapp_storage(d);
573
+ dapp_service::destroy_dapp_hub(dh);
574
+ }
575
+
576
+ #[test]
577
+ #[expected_failure]
578
+ fun test_delete_global_record_aborts_on_dapp_key_mismatch() {
579
+ let mut ctx = sui::tx_context::dummy();
580
+ let dh = make_dh(&mut ctx);
581
+ // Write a record with the correct key first.
582
+ let mut d = dapp_service::create_dapp_storage_for_testing<StoreKey>(&mut ctx);
583
+ dapp_system::set_global_record<StoreKey>(
584
+ StoreKey {}, &mut d, k(b"g"), fns(), u32_val(1), false
585
+ );
586
+ // Attempt delete with the wrong key — must abort with dapp_key_mismatch.
587
+ dapp_system::delete_global_record<WrongKey>(WrongKey {}, &mut d, k(b"g"), fns());
588
+ dapp_service::destroy_dapp_storage(d);
589
+ dapp_service::destroy_dapp_hub(dh);
590
+ }
591
+
592
+ #[test]
593
+ #[expected_failure]
594
+ fun test_delete_global_field_aborts_on_dapp_key_mismatch() {
595
+ let mut ctx = sui::tx_context::dummy();
596
+ let dh = make_dh(&mut ctx);
597
+ let mut d = dapp_service::create_dapp_storage_for_testing<StoreKey>(&mut ctx);
598
+ dapp_system::set_global_record<StoreKey>(
599
+ StoreKey {}, &mut d, k(b"g"), vector[b"a", b"b"],
600
+ vector[to_bytes(&1u32), to_bytes(&2u32)], false
601
+ );
602
+ // Attempt field delete with the wrong key — must abort with dapp_key_mismatch.
603
+ dapp_system::delete_global_field<WrongKey>(WrongKey {}, &mut d, k(b"g"), b"a");
604
+ dapp_service::destroy_dapp_storage(d);
605
+ dapp_service::destroy_dapp_hub(dh);
606
+ }
607
+
608
+ // ═══════════════════════════════════════════════════════════════════════════════
609
+ // UserStorage — set_field at write limit
610
+ // ═══════════════════════════════════════════════════════════════════════════════
611
+
612
+ #[test]
613
+ #[expected_failure]
614
+ fun test_set_field_aborts_at_write_limit() {
615
+ let mut ctx = sui::tx_context::dummy();
616
+ let dh = make_dh(&mut ctx);
617
+ let mut us = us_owned(&mut ctx);
618
+
619
+ // Create a record so the sentinel exists for set_field.
620
+ dapp_system::set_record<StoreKey>(StoreKey {}, &mut us, k(b"p"), fns(), u32_val(1), false, &mut ctx);
621
+
622
+ // set_record above counted as 1 write; add 999 more to reach MAX_UNSETTLED_WRITES (1000).
623
+ let mut i = 1u64;
624
+ while (i < 1000) {
625
+ dapp_service::increment_write_count(&mut us);
626
+ i = i + 1;
627
+ };
628
+
629
+ // At the limit: unsettled count >= MAX_UNSETTLED_WRITES → set_field must abort.
630
+ dapp_system::set_field<StoreKey>(StoreKey {}, &mut us, k(b"p"), b"v", to_bytes(&99u32), &mut ctx);
631
+ dapp_service::destroy_user_storage(us);
632
+ dapp_service::destroy_dapp_hub(dh);
633
+ }
634
+
635
+ // ═══════════════════════════════════════════════════════════════════════════════
636
+ // ELengthMismatch — field_names / values length mismatch
637
+ // ═══════════════════════════════════════════════════════════════════════════════
638
+
639
+ #[test]
640
+ #[expected_failure]
641
+ fun test_set_record_aborts_on_length_mismatch() {
642
+ let mut ctx = sui::tx_context::dummy();
643
+ let dh = make_dh(&mut ctx);
644
+ let mut us = us_owned(&mut ctx);
645
+ // 2 field names but only 1 value → ELengthMismatch.
646
+ dapp_system::set_record<StoreKey>(
647
+ StoreKey {}, &mut us, k(b"x"),
648
+ vector[b"a", b"b"],
649
+ vector[to_bytes(&1u32)],
650
+ false, &mut ctx
651
+ );
652
+ dapp_service::destroy_user_storage(us);
653
+ dapp_service::destroy_dapp_hub(dh);
654
+ }
655
+
656
+ #[test]
657
+ #[expected_failure]
658
+ fun test_set_global_record_aborts_on_length_mismatch() {
659
+ let mut ctx = sui::tx_context::dummy();
660
+ let dh = make_dh(&mut ctx);
661
+ let mut d = ds(&mut ctx);
662
+ // 2 field names but only 1 value → ELengthMismatch.
663
+ // Note: field_names / values length mismatch → ELengthMismatch.
664
+ dapp_system::set_global_record<StoreKey>(
665
+ StoreKey {}, &mut d, k(b"x"),
666
+ vector[b"a", b"b"],
667
+ vector[to_bytes(&1u32)],
668
+ false
669
+ );
670
+ dapp_service::destroy_dapp_storage(d);
671
+ dapp_service::destroy_dapp_hub(dh);
672
+ }
673
+
674
+ // ═══════════════════════════════════════════════════════════════════════════════
675
+ // EInvalidKey — set_field / set_global_field on a non-existent record
676
+ // ═══════════════════════════════════════════════════════════════════════════════
677
+
678
+ #[test]
679
+ #[expected_failure]
680
+ fun test_set_field_aborts_on_missing_record() {
681
+ let mut ctx = sui::tx_context::dummy();
682
+ let dh = make_dh(&mut ctx);
683
+ let mut us = us_owned(&mut ctx);
684
+ // No record created at k(b"ghost") → set_user_field must abort with EInvalidKey.
685
+ dapp_system::set_field<StoreKey>(StoreKey {}, &mut us, k(b"ghost"), b"v", to_bytes(&1u32), &mut ctx);
686
+ dapp_service::destroy_user_storage(us);
687
+ dapp_service::destroy_dapp_hub(dh);
688
+ }
689
+
690
+ #[test]
691
+ #[expected_failure]
692
+ fun test_set_global_field_aborts_on_missing_record() {
693
+ let mut ctx = sui::tx_context::dummy();
694
+ let dh = make_dh(&mut ctx);
695
+ let mut d = ds(&mut ctx);
696
+ // No record created at k(b"ghost") → set_global_field must abort with EInvalidKey.
697
+ dapp_system::set_global_field<StoreKey>(StoreKey {}, &mut d, k(b"ghost"), b"v", to_bytes(&1u32));
698
+ dapp_service::destroy_dapp_storage(d);
699
+ dapp_service::destroy_dapp_hub(dh);
700
+ }