create-dubhe 1.2.0-pre.99 → 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 (360) 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 +4 -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 +4 -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/sources/codegen/dapp_key.move +45 -31
  297. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/error.move +10 -0
  298. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/genesis.move +30 -13
  299. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/init_test.move +19 -14
  300. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter1.move +30 -20
  301. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/resources/counter2.move +35 -24
  302. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/user_storage_init.move +26 -0
  303. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/scripts/deploy_hook.move +6 -10
  304. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/systems/counter.move +7 -20
  305. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/tests/counter.move +14 -27
  306. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.lock +33 -30
  307. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.toml +4 -3
  308. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move +45 -31
  309. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/error.move +170 -0
  310. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/genesis.move +16 -13
  311. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/init_test.move +8 -14
  312. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/account_key.move +1 -3
  313. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move +1776 -137
  314. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/data_key.move +1 -20
  315. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/events.move +864 -25
  316. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/scripts/deploy_hook.move +15 -16
  317. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/scripts/migrate.move +0 -3
  318. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/address_system.move +25 -17
  319. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +2802 -343
  320. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/utils.move +1 -1
  321. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/address.move +173 -55
  322. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/dapp_test.move +769 -0
  323. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +2965 -0
  324. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move +303 -0
  325. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/listing_test.move +1422 -0
  326. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/scene_session_test.move +269 -0
  327. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/session_test.move +624 -0
  328. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/storage_test.move +700 -0
  329. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_object_test.move +177 -0
  330. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_scene_test.move +452 -0
  331. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/user_storage_test.move +160 -0
  332. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/utils/math.move +4 -3
  333. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/utils/type_info.move +2 -2
  334. package/templates/101/sui-template/packages/contracts/src/counter/Move.lock +0 -41
  335. package/templates/101/sui-template/packages/contracts/src/counter/Published.toml +0 -9
  336. package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/errors.move +0 -12
  337. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/errors.move +0 -140
  338. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  339. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  340. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  341. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  342. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/dapp_store.move +0 -29
  343. package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/session_system.move +0 -44
  344. package/templates/contract/sui-template/src/dubhe/sources/codegen/errors.move +0 -140
  345. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  346. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  347. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  348. package/templates/contract/sui-template/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  349. package/templates/contract/sui-template/src/dubhe/sources/core/dapp_store.move +0 -29
  350. package/templates/contract/sui-template/src/dubhe/sources/systems/session_system.move +0 -44
  351. package/templates/nextjs/sui-template/packages/contracts/src/counter/Move.lock +0 -47
  352. package/templates/nextjs/sui-template/packages/contracts/src/counter/Published.toml +0 -9
  353. package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/errors.move +0 -12
  354. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/errors.move +0 -140
  355. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_config.move +0 -186
  356. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_fee_state.move +0 -306
  357. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dapp_metadata.move +0 -396
  358. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/resources/dubhe_config.move +0 -246
  359. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/dapp_store.move +0 -29
  360. package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/session_system.move +0 -44
@@ -0,0 +1,160 @@
1
+ /// Unit tests — UserStorage creation and registration
2
+ ///
3
+ /// Covers:
4
+ /// create_user_storage: initial state, registration recorded, duplicate abort
5
+ /// canonical_owner is set correctly on creation
6
+ /// session fields initialized to zero/empty
7
+ #[test_only]
8
+ module dubhe::user_storage_test;
9
+
10
+ use dubhe::dapp_service::{Self, DappHub, DappStorage};
11
+ use dubhe::dapp_system;
12
+ use sui::test_scenario;
13
+
14
+ public struct UsTestKey has copy, drop {}
15
+
16
+ const USER: address = @0x1234;
17
+
18
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
19
+
20
+ fun setup(scenario: &mut test_scenario::Scenario): (DappHub, DappStorage) {
21
+ let ctx = test_scenario::ctx(scenario);
22
+ (
23
+ dapp_system::create_dapp_hub_for_testing(ctx),
24
+ dapp_system::create_dapp_storage_for_testing<UsTestKey>(ctx),
25
+ )
26
+ }
27
+
28
+ // ═══════════════════════════════════════════════════════════════════════════════
29
+ // Initial state
30
+ // ═══════════════════════════════════════════════════════════════════════════════
31
+
32
+ #[test]
33
+ fun test_initial_write_counts_are_zero() {
34
+ let mut scenario = test_scenario::begin(USER);
35
+ {
36
+ let ctx = test_scenario::ctx(&mut scenario);
37
+ let us = dapp_service::create_user_storage_for_testing<UsTestKey>(USER, ctx);
38
+
39
+ assert!(dapp_service::write_count(&us) == 0);
40
+ assert!(dapp_service::settled_count(&us) == 0);
41
+ assert!(dapp_service::unsettled_count(&us) == 0);
42
+
43
+ dapp_service::destroy_user_storage(us);
44
+ };
45
+ scenario.end();
46
+ }
47
+
48
+ #[test]
49
+ fun test_canonical_owner_set_on_creation() {
50
+ let mut scenario = test_scenario::begin(USER);
51
+ {
52
+ let ctx = test_scenario::ctx(&mut scenario);
53
+ let us = dapp_service::create_user_storage_for_testing<UsTestKey>(USER, ctx);
54
+ assert!(dapp_service::canonical_owner(&us) == USER);
55
+ dapp_service::destroy_user_storage(us);
56
+ };
57
+ scenario.end();
58
+ }
59
+
60
+ #[test]
61
+ fun test_session_fields_cleared_on_creation() {
62
+ let mut scenario = test_scenario::begin(USER);
63
+ {
64
+ let ctx = test_scenario::ctx(&mut scenario);
65
+ let us = dapp_service::create_user_storage_for_testing<UsTestKey>(USER, ctx);
66
+ assert!(dapp_service::session_key(&us) == @0x0);
67
+ assert!(dapp_service::session_expires_at(&us) == 0);
68
+ dapp_service::destroy_user_storage(us);
69
+ };
70
+ scenario.end();
71
+ }
72
+
73
+ // ═══════════════════════════════════════════════════════════════════════════════
74
+ // create_user_storage (via dapp_system) — registration guard
75
+ // ═══════════════════════════════════════════════════════════════════════════════
76
+
77
+ #[test]
78
+ fun test_create_user_storage_registers_address() {
79
+ let sender = @0xABC;
80
+ let mut scenario = test_scenario::begin(sender);
81
+ {
82
+ let (dh, mut ds) = setup(&mut scenario);
83
+ let ctx = test_scenario::ctx(&mut scenario);
84
+
85
+ assert!(!dapp_service::has_registered_user_storage(&ds, sender));
86
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
87
+ assert!(dapp_service::has_registered_user_storage(&ds, sender));
88
+
89
+ dapp_system::destroy_dapp_hub(dh);
90
+ dapp_system::destroy_dapp_storage(ds);
91
+ };
92
+ scenario.end();
93
+ }
94
+
95
+ #[test]
96
+ #[expected_failure]
97
+ fun test_create_user_storage_twice_aborts() {
98
+ let sender = @0xABC;
99
+ let mut scenario = test_scenario::begin(sender);
100
+ {
101
+ let (dh, mut ds) = setup(&mut scenario);
102
+ let ctx = test_scenario::ctx(&mut scenario);
103
+
104
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
105
+ // Second call from the same address must abort with user_storage_already_exists.
106
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
107
+
108
+ dapp_system::destroy_dapp_hub(dh);
109
+ dapp_system::destroy_dapp_storage(ds);
110
+ };
111
+ scenario.end();
112
+ }
113
+
114
+ #[test]
115
+ fun test_different_users_can_each_create_one_user_storage() {
116
+ let user_a = @0xAAAA;
117
+ let user_b = @0xBBBB;
118
+
119
+ let mut scenario = test_scenario::begin(user_a);
120
+ {
121
+ let (dh, mut ds) = setup(&mut scenario);
122
+
123
+ // user_a creates their storage.
124
+ let ctx = test_scenario::ctx(&mut scenario);
125
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
126
+ assert!(dapp_service::has_registered_user_storage(&ds, user_a));
127
+
128
+ // user_b creates theirs in a new tx.
129
+ test_scenario::next_tx(&mut scenario, user_b);
130
+ let ctx = test_scenario::ctx(&mut scenario);
131
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
132
+ assert!(dapp_service::has_registered_user_storage(&ds, user_b));
133
+
134
+ dapp_system::destroy_dapp_hub(dh);
135
+ dapp_system::destroy_dapp_storage(ds);
136
+ };
137
+ scenario.end();
138
+ }
139
+
140
+ // ═══════════════════════════════════════════════════════════════════════════════
141
+ // Suspended DApp guard
142
+ // ═══════════════════════════════════════════════════════════════════════════════
143
+
144
+ #[test]
145
+ fun test_create_user_storage_succeeds_after_registration_check() {
146
+ let sender = @0xABC;
147
+ let mut scenario = test_scenario::begin(sender);
148
+ {
149
+ let (dh, mut ds) = setup(&mut scenario);
150
+ let ctx = test_scenario::ctx(&mut scenario);
151
+
152
+ // Must succeed.
153
+ dapp_system::create_user_storage(UsTestKey {}, &dh, &mut ds, ctx);
154
+ assert!(dapp_service::has_registered_user_storage(&ds, sender));
155
+
156
+ dapp_system::destroy_dapp_hub(dh);
157
+ dapp_system::destroy_dapp_storage(ds);
158
+ };
159
+ scenario.end();
160
+ }
@@ -1,6 +1,7 @@
1
1
  module dubhe::dubhe_math {
2
2
  use std::u128;
3
3
  use std::u64;
4
+ use dubhe::error;
4
5
 
5
6
  public fun min(x: u256, y: u256): u256 {
6
7
  if (x < y) x else y
@@ -9,12 +10,12 @@ module dubhe::dubhe_math {
9
10
  public fun safe_mul(a: u256, b: u256): u256 {
10
11
  if (a == 0 || b == 0) return 0;
11
12
  let c = a * b;
12
- assert!(c / a == b, 0);
13
+ error::math_overflow(c / a == b);
13
14
  c
14
15
  }
15
16
 
16
17
  public fun safe_div(a: u256, b: u256): u256 {
17
- assert!(b != 0, 0);
18
+ error::division_by_zero(b != 0);
18
19
  a / b
19
20
  }
20
21
 
@@ -108,7 +109,7 @@ module dubhe::dubhe_math {
108
109
  }
109
110
 
110
111
  public(package) fun windows(x: &vector<u256>, size: u64): vector<vector<u256>> {
111
- assert!(size > 0, 0);
112
+ error::invalid_window_size(size > 0);
112
113
 
113
114
  let length = vector::length(x);
114
115
  let mut result = vector::empty<vector<u256>>();
@@ -29,11 +29,11 @@ module dubhe::type_info {
29
29
  }
30
30
 
31
31
  public fun get_package_id<T>(): address {
32
- let type_name = type_name::get<T>().get_address();
32
+ let type_name = type_name::with_defining_ids<T>().address_string();
33
33
  address::from_ascii_bytes(type_name.as_bytes())
34
34
  }
35
35
 
36
36
  public fun get_type_name_string<T>(): String {
37
- type_name::get<T>().into_string()
37
+ type_name::with_defining_ids<T>().into_string()
38
38
  }
39
39
  }
@@ -0,0 +1,12 @@
1
+ [package]
2
+ name = "template"
3
+ version = "1.0.0"
4
+ edition = "2024"
5
+
6
+ [dependencies]
7
+ Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet-v1.68.1" }
8
+ Dubhe = { git = "https://github.com/0xobelisk/dubhe.git", subdir = "framework/src/dubhe", rev = "v1.2.0-pre.112" }
9
+
10
+ [addresses]
11
+ sui = "0x2"
12
+ template = "0x0"
@@ -0,0 +1,47 @@
1
+ // Copyright (c) Obelisk Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ #[allow(unused_use)]
4
+
5
+ /* Autogenerated file. Do not edit manually. */
6
+
7
+ module template::dapp_key {
8
+ use std::type_name;
9
+ use sui::address;
10
+ use std::ascii::String;
11
+
12
+ /// DappKey — package-level authorization token for this DApp.
13
+ ///
14
+ /// SECURITY: `new()` is intentionally `public(package)`.
15
+ /// Only code compiled into this package can construct a DappKey instance.
16
+ /// All framework write functions (`set_record`, `set_field`,
17
+ /// `take_record`, `create_user_storage`, …) require `_auth: DappKey`
18
+ /// as proof that the call originated from inside this package — an
19
+ /// external PTB cannot fabricate that proof.
20
+ ///
21
+ /// NEVER change `new()` to `public`, and never accept a DappKey
22
+ /// value as a parameter from an external caller. Either mistake removes
23
+ /// every package-level access guard, allowing any PTB to write arbitrary
24
+ /// user data or register UserStorages without going through the DApp's
25
+ /// own entry functions.
26
+
27
+ public struct DappKey has copy, drop {}
28
+
29
+ /// Constructs an authorization token. Callable only from within this package.
30
+ /// Pass the result as `_auth` to any framework function that requires it.
31
+ public(package) fun new(): DappKey {
32
+ DappKey {}
33
+ }
34
+
35
+ public fun to_string(): String {
36
+ type_name::get<DappKey>().into_string()
37
+ }
38
+
39
+ public fun package_id(): address {
40
+ let package_id_str = type_name::get<DappKey>().get_address();
41
+ address::from_ascii_bytes(package_id_str.as_bytes())
42
+ }
43
+
44
+ public fun eq<DappKey1: copy + drop, DappKey2: copy + drop>(_: &DappKey1, _: &DappKey2): bool {
45
+ type_name::get<DappKey1>() == type_name::get<DappKey2>()
46
+ }
47
+ }
@@ -0,0 +1,34 @@
1
+ #[allow(lint(share_owned))]
2
+ module template::genesis {
3
+ use sui::clock::Clock;
4
+ use dubhe::dapp_service::{DappHub, DappStorage};
5
+ use template::dapp_key;
6
+ use dubhe::dapp_system;
7
+ use std::ascii::string;
8
+ use sui::transfer;
9
+
10
+ // The one-shot guard is enforced inside dapp_system::create_dapp, which
11
+ // records the DappKey type in DappHub before returning DappStorage.
12
+ // genesis.move does not need to carry its own guard.
13
+ public entry fun run(dapp_hub: &mut DappHub, clock: &Clock, ctx: &mut TxContext) {
14
+ // create_dapp aborts with dapp_already_initialized_error on repeated calls.
15
+ let dapp_key = dapp_key::new();
16
+ let mut ds = dapp_system::create_dapp(dapp_key, dapp_hub, string(b"template"), string(b"template"), 0, clock, ctx);
17
+
18
+ // Set up initial DApp state (e.g. default resource values).
19
+ template::deploy_hook::run(&mut ds, ctx);
20
+
21
+ // Share DappStorage so every transaction can access it.
22
+ transfer::public_share_object(ds);
23
+ }
24
+
25
+ // Called during contract upgrades to register newly added resource tables
26
+ // and run any custom migration logic. `dubhe upgrade` rewrites the region
27
+ // between the separator comments; do not edit that block manually.
28
+ public(package) fun migrate(_dapp_hub: &mut DappHub, _dapp_storage: &mut DappStorage, _ctx: &mut TxContext) {
29
+ // ==========================================
30
+ // Add custom migration logic here (e.g. initialise new resource defaults).
31
+ // migrate_to_vN in migrate.move calls this function automatically.
32
+ // ==========================================
33
+ }
34
+ }
@@ -0,0 +1,23 @@
1
+ #[test_only]
2
+
3
+ module template::init_test {
4
+ use dubhe::dapp_system;
5
+
6
+ /// Create a DappHub for testing without sharing it.
7
+ /// Suitable for unit tests that need a DappHub context.
8
+ public fun create_dapp_hub_for_testing(ctx: &mut TxContext): dubhe::dapp_service::DappHub {
9
+ dapp_system::create_dapp_hub_for_testing(ctx)
10
+ }
11
+
12
+ /// Create a DappStorage for this DApp without sharing it.
13
+ /// Suitable for unit tests that exercise global-resource functions.
14
+ public fun create_dapp_storage_for_testing(ctx: &mut TxContext): dubhe::dapp_service::DappStorage {
15
+ dubhe::dapp_system::create_dapp_storage_for_testing<template::dapp_key::DappKey>(ctx)
16
+ }
17
+
18
+ /// Create a UserStorage for `owner` without sharing it.
19
+ /// Suitable for unit tests that exercise user-level resource functions.
20
+ public fun create_user_storage_for_testing(owner: address, ctx: &mut TxContext): dubhe::dapp_service::UserStorage {
21
+ dubhe::dapp_system::create_user_storage_for_testing<template::dapp_key::DappKey>(owner, ctx)
22
+ }
23
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright (c) Obelisk Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ #[allow(unused_use)]
4
+
5
+ /* Autogenerated file. Do not edit manually. */
6
+
7
+ module template::user_storage_init {
8
+ use dubhe::dapp_service::{DappHub, DappStorage};
9
+ use dubhe::dapp_system;
10
+ use template::dapp_key;
11
+ use template::dapp_key::DappKey;
12
+ use template::migrate;
13
+
14
+ /// Create a UserStorage for the transaction sender within this DApp.
15
+ /// Must be called once before the user can interact with any user-level resources.
16
+ /// Aborts if the DApp version does not match this package, the DApp is paused,
17
+ /// or the framework version has advanced.
18
+ #[allow(lint(public_entry))]
19
+ public entry fun init_user_storage(
20
+ dapp_hub: &DappHub,
21
+ dapp_storage: &mut DappStorage,
22
+ ctx: &mut TxContext,
23
+ ) {
24
+ dapp_system::ensure_latest_version<DappKey>(dapp_storage, migrate::on_chain_version());
25
+ dapp_system::create_user_storage(dapp_key::new(), dapp_hub, dapp_storage, ctx);
26
+ }
27
+ }
@@ -0,0 +1,13 @@
1
+ // Copyright (c) Obelisk Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ #[allow(unused_use)]
4
+
5
+ /* Autogenerated file. Do not edit manually. */
6
+
7
+ module template::deploy_hook {
8
+ use dubhe::dapp_service::DappStorage;
9
+
10
+ public(package) fun run(_dapp_storage: &mut DappStorage, _ctx: &mut TxContext) {
11
+ // Initialise any DappStorage-level defaults here.
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ module template::migrate {
2
+ const ON_CHAIN_VERSION: u32 = 1;
3
+
4
+ public fun on_chain_version(): u32 {
5
+ ON_CHAIN_VERSION
6
+ }
7
+ }
@@ -0,0 +1,51 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.*
7
+ .yarn/*
8
+ !.yarn/patches
9
+ !.yarn/plugins
10
+ !.yarn/releases
11
+ !.yarn/versions
12
+
13
+ # testing
14
+ /coverage
15
+
16
+ # next.js
17
+ /.next/
18
+ /out/
19
+
20
+ # production
21
+ /build
22
+
23
+ # misc
24
+ .DS_Store
25
+ *.pem
26
+
27
+ # debug
28
+ npm-debug.log*
29
+ yarn-debug.log*
30
+ yarn-error.log*
31
+ .pnpm-debug.log*
32
+
33
+ # env files (can opt-in for committing if needed)
34
+ .env*
35
+
36
+ # vercel
37
+ .vercel
38
+
39
+ # typescript
40
+ *.tsbuildinfo
41
+ next-env.d.ts
42
+
43
+ # dubhe
44
+ contracts/dubhe-framework/.history
45
+ contracts/dubhe-framework/Move.lock
46
+ **/build/
47
+ src/chain/key.ts
48
+ indexer.db
49
+ node_logs
50
+ mprocs.log
51
+ .data/
@@ -0,0 +1,213 @@
1
+ # Card Duel — full-chain PvP card battles on Sui
2
+
3
+ Card Duel is a Dubhe template that demonstrates every storage tier and
4
+ authorization primitive of the framework in one playable game: 1v1 duels
5
+ with gold stakes, multiplayer brawl rooms, a card marketplace, and an
6
+ on-chain arena treasury that collects a rake from every match. All match
7
+ actions are signed silently by a session key while every on-chain identity
8
+ resolves to the player's main wallet.
9
+
10
+ ## Gameplay
11
+
12
+ The game is a turn-based card battler with a closed gold economy.
13
+
14
+ ### Onboarding
15
+
16
+ Connect a wallet, create your UserStorage, and register. Registration grants
17
+ 500 gold and a 5-card starter deck (3× Strike, 1× Fireball, 1× Shield).
18
+ Activate a session key from the banner to play without wallet popups.
19
+
20
+ ### Cards and decks
21
+
22
+ Every card has a kind and a rarity. Kinds decide what the card does; rarity
23
+ multiplies its power.
24
+
25
+ | Kind | Effect | Base power | Pack odds |
26
+ | -------- | -------------------- | ---------- | --------- |
27
+ | Strike | damage to a target | 12 | 40% |
28
+ | Fireball | damage to a target | 18 | 25% |
29
+ | Heal | restore your HP | 10 | 20% |
30
+ | Shield | absorb future damage | 8 | 15% |
31
+
32
+ | Rarity | Pack odds | Power bonus |
33
+ | ------ | --------- | ----------- |
34
+ | Common | 70% | — |
35
+ | Rare | 25% | +1/3 |
36
+ | Epic | 5% | +3/4 |
37
+
38
+ Card packs cost 100 gold and mint one random card using `sui::random`.
39
+ Your battle deck is exactly 5 distinct cards you own; editing the deck is
40
+ free (ownership is verified on-chain).
41
+
42
+ ### Duel (1v1, direct invitation)
43
+
44
+ Challenge a specific address with a gold stake. Your stake is escrowed into
45
+ the match scene immediately; the opponent's stake joins the pot when they
46
+ accept. Players alternate turns at 30 HP each, and every card can be played
47
+ once per duel. Knock the opponent to 0 HP, then collect the pot minus the
48
+ 3% arena rake. Surrender concedes the pot; a player who stalls past the
49
+ 5-minute turn timeout can be claimed against. The challenger can cancel a
50
+ pending invite for a full refund.
51
+
52
+ ### Brawl (1vN, open room)
53
+
54
+ Open a room with an entry fee and a player cap (2–8). Anyone can join until
55
+ the room is full; joining escrows the fee, and leaving an open room refunds
56
+ it. Once at least two players are in, the host starts the match. Turns
57
+ rotate through the alive list; attack cards require picking a target, and
58
+ cards are reusable between turns. Eliminated players drop out of rotation,
59
+ stalling players can be kicked on timeout, and the last player standing
60
+ collects the whole pot (minus rake).
61
+
62
+ ### Market, leaderboard, and admin
63
+
64
+ - **Market** — list cards (NFT-style records) or gold (fungible amounts)
65
+ for SUI. Purchases settle through the framework marketplace with
66
+ automatic fee splitting. Trades require the main wallet.
67
+ - **Leaderboard** — ladder rating (1200 start, ±25 per match) read from the
68
+ indexer.
69
+ - **Admin** — the deployer wallet configures the arena display data and the
70
+ game config (pack price, starting gold, rake, HP, turn timeout), and
71
+ withdraws the accumulated rake from the arena treasury into its own gold
72
+ balance.
73
+
74
+ The economy loop: win matches to earn gold, spend gold on packs to chase
75
+ Rare/Epic cards, build a stronger deck, and sell surplus cards for SUI.
76
+
77
+ ## Dubhe feature coverage
78
+
79
+ Use this template as a reference when you need a working example of a
80
+ specific framework capability.
81
+
82
+ | Capability | Where it is demonstrated |
83
+ | ----------------------------------- | ----------------------------------------------------------------------------------------- |
84
+ | UserStorage resources | `gold`, `profile`, `deck`, `battle_state`, `card` (per-player state) |
85
+ | Global resources | `game_config` (singleton, set by `deploy_hook` / `arena_system::set_game_config`) |
86
+ | ObjectStorage (named shared object) | `arena` treasury — created by `deploy_hook` (entity id `"main"`), admin-only field writes |
87
+ | SceneStorage (multi-user object) | `duel` and `brawl` matches (escrowed pot + turn state) |
88
+ | ScenePermit: direct invitations | `duel_system::create_duel` — only the invited opponent can accept |
89
+ | ScenePermit: open invitations | `brawl_system::create_brawl` — anyone joins until the room is full |
90
+ | Reactive writes (cross-user) | combat damage and loss records written to the opponent's UserStorage |
91
+ | Transferable resources | gold moves User ⇄ Scene (stake escrow), Scene → Object (rake), Object → User (withdraw) |
92
+ | Listable resources / marketplace | `market_system` — card NFTs and fungible gold listed for SUI |
93
+ | Session keys + canonical owner | every match action is session-signed; on-chain identity resolves to the main wallet |
94
+ | Randomness | `card_system::open_pack` uses `sui::random::Random` |
95
+ | Indexer system tables | `dubheSceneStorages`, `dubheObjectStorages`, `dubheSessions`, marketplace tables |
96
+ | Deploy hook | `deploy_hook` initialises the game config and creates the shared arena at publish time |
97
+
98
+ ## Session keys and identity
99
+
100
+ Match actions (create, accept, attack, defend, finish, leave) are signed by
101
+ an ephemeral session key once you activate one from the header — no wallet
102
+ popup per move. The contracts never use the transaction sender as the player
103
+ identity: every system resolves the player through
104
+ `dapp_service::canonical_owner(user_storage)`, so permit participants, scene
105
+ fields, profiles, and gold are always recorded under the main wallet address
106
+ even when a session key signs. Revoking the session
107
+ (`dapp_system::deactivate_session`) immediately removes its write access.
108
+
109
+ On the client, session state is scoped per (network, main wallet address):
110
+ each account keeps its own ephemeral keypair, switching accounts never shows
111
+ another account's session, and the local state is revalidated against the
112
+ indexer's `dubheSessions` table so sessions revoked elsewhere disappear
113
+ automatically.
114
+
115
+ Onboarding (UserStorage creation, registration, session activation) and
116
+ marketplace trades still require the main wallet because they move SUI or
117
+ establish the delegation itself.
118
+
119
+ ## Verified behaviour
120
+
121
+ The template ships with two layers of tests, both runnable against this
122
+ repository.
123
+
124
+ ### Move unit tests (29 cases, `pnpm test`)
125
+
126
+ - **Duel lifecycle** — full flow from registration to knockout, settlement
127
+ (pot minus rake), profile/rating updates, and scene cleanup; cancel with
128
+ refund; surrender; timeout claims (success and "too early" failure).
129
+ - **Session delegation** — a session key plays a full duel for its canonical
130
+ owner; an unauthorized signer is rejected.
131
+ - **Guard rails** — self-challenge, zero stake, insufficient gold, uninvited
132
+ accept, out-of-turn attack, card reuse within a duel, attack card played
133
+ as defense, double-matching, loser attempting settlement, wrong deck size,
134
+ duplicate deck cards, double registration.
135
+ - **Brawl lifecycle** — three-player flow with eliminations and pot
136
+ collection; entry-fee refunds on leave; full-room join rejection; host
137
+ leave/start restrictions; out-of-turn attacks; surrender deciding a match;
138
+ timeout kicks.
139
+
140
+ ### End-to-end scripts (against a running localnet stack)
141
+
142
+ | Script | What it verifies |
143
+ | ------------------------ | ------------------------------------------------------------------------------------------------- |
144
+ | `scripts/e2e-duel.ts` | duel flow + indexer state (gold, profiles, scene destruction) |
145
+ | `scripts/e2e-brawl.ts` | brawl flow + `open_pack` randomness + balance assertions |
146
+ | `scripts/e2e-session.ts` | session key plays a full duel; identity resolves to the main wallet; revoked sessions lose access |
147
+ | `scripts/e2e-lobby.ts` | the client's scene-discovery queries (dappKey-filtered) against live GraphQL |
148
+ | `scripts/e2e-market.ts` | card/gold listing, purchase, and listing closure |
149
+
150
+ `open_pack` and the market system are covered by the e2e layer rather than
151
+ unit tests because they depend on `sui::random` and marketplace settlement.
152
+
153
+ ## Requirements
154
+
155
+ - Node.js 18.20+ and pnpm 9+
156
+ - [Sui CLI](https://docs.sui.io/build/install)
157
+ - Docker (for the indexer's PostgreSQL + GraphQL server)
158
+
159
+ ## Quick start
160
+
161
+ Run everything (localnet node, contract deployment, indexer, GraphQL server,
162
+ and the Next.js client) with one command from the template root:
163
+
164
+ ```bash
165
+ pnpm install
166
+ pnpm dev
167
+ ```
168
+
169
+ `pnpm dev` opens an mprocs dashboard with five processes: `node` (localnet),
170
+ `contracts` (deploy + indexer), `graphql` (Docker), `client` (Next.js on
171
+ http://localhost:3000), and an interactive `shell`. Wait until the client
172
+ process reports "Ready", then open the app and connect a Sui wallet that is
173
+ set to localnet.
174
+
175
+ To seed a custom game configuration after deployment:
176
+
177
+ ```bash
178
+ cd packages/contracts
179
+ pnpm seed:localnet
180
+ ```
181
+
182
+ ## Project structure
183
+
184
+ ```
185
+ packages/
186
+ contracts/
187
+ dubhe.config.ts # resources, objects, scenes, permits, errors
188
+ src/card_duel/
189
+ sources/systems/ # player / card / duel / brawl / arena / market
190
+ sources/scripts/ # deploy_hook (game config + arena creation)
191
+ sources/tests/ # Move unit tests (pnpm test)
192
+ scripts/ # seed, revenue, and e2e verification scripts
193
+ client/
194
+ src/app/ # lobby, collection, duel/[id], brawl/[id],
195
+ # market, leaderboard, admin
196
+ src/app/lib/ # bcs decoders, scene discovery, game constants
197
+ src/app/hooks/ # useGame (state + tx), useSessionKey
198
+ ```
199
+
200
+ ## Useful commands
201
+
202
+ Run these from `packages/contracts` unless noted otherwise.
203
+
204
+ | Command | Purpose |
205
+ | ---------------------------------------- | -------------------------------------------------------------------- |
206
+ | `pnpm test` | Move unit tests (29 cases) |
207
+ | `pnpm tsx scripts/e2e-duel.ts` | Scripted 1v1 duel against a running localnet stack |
208
+ | `pnpm tsx scripts/e2e-brawl.ts` | Scripted brawl + pack opening |
209
+ | `pnpm tsx scripts/e2e-session.ts` | Full duel played by a session key; verifies canonical-owner identity |
210
+ | `pnpm tsx scripts/e2e-market.ts` | Scripted card/gold listing and purchase |
211
+ | `pnpm tsx scripts/e2e-lobby.ts` | Verifies the client's indexer queries; seeds lobby data |
212
+ | `pnpm seed:localnet` | Re-apply the default game configuration |
213
+ | `pnpm tsx scripts/query-dapp-revenue.ts` | Inspect DApp fee revenue |