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,622 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect, useCallback } from 'react';
4
+ import { ConnectButton, useCurrentAccount, useSignAndExecuteTransaction } from '@mysten/dapp-kit';
5
+ import { useDubhe } from '@0xobelisk/react/sui';
6
+ import { Transaction, SuiClient } from '@0xobelisk/sui-client';
7
+ import { toast } from 'sonner';
8
+ import { DappHubId, DappStorageId, Network } from 'contracts/deployment';
9
+ import { ArenaPanel } from './ArenaPanel';
10
+
11
+ const fallbackExplorerUrl = (digest: string, network: string) =>
12
+ `https://suiscan.xyz/${network}/tx/${digest}`;
13
+
14
+ // ── Types ─────────────────────────────────────────────────────────────────────
15
+
16
+ interface FeeState {
17
+ baseFeePerWrite: bigint;
18
+ bytesFeePerByte: bigint;
19
+ freeCredit: bigint;
20
+ creditPool: bigint;
21
+ totalSettled: bigint;
22
+ settlementMode: number;
23
+ writeFeeDappShareBps: number;
24
+ }
25
+
26
+ interface RevenueState {
27
+ dappRevenue: bigint;
28
+ coinType: string;
29
+ }
30
+
31
+ interface RuntimeState {
32
+ admin: string;
33
+ paused: boolean;
34
+ lastRuntimeEvent: string;
35
+ lastRuntimeActor: string;
36
+ lastRuntimeAmount: string;
37
+ }
38
+
39
+ interface MarketplaceFeeRecord {
40
+ listingId: string;
41
+ coinType: string;
42
+ totalFee: bigint;
43
+ treasuryAmount: bigint;
44
+ dappAmount: bigint;
45
+ updatedAtCheckpoint: string;
46
+ }
47
+
48
+ interface SettlementRecord {
49
+ digest: string;
50
+ account: string;
51
+ writes: number;
52
+ paidCost: bigint;
53
+ timestampMs: number;
54
+ }
55
+
56
+ interface FrameworkTreasury {
57
+ address: string;
58
+ balance: bigint;
59
+ }
60
+
61
+ // ── Helpers ───────────────────────────────────────────────────────────────────
62
+
63
+ const MIST_PER_SUI = 1_000_000_000n;
64
+ const formatMist = (mist: bigint) => (Number(mist) / Number(MIST_PER_SUI)).toFixed(6) + ' SUI';
65
+ const shortAddr = (addr: string) => (addr ? `${addr.slice(0, 8)}…${addr.slice(-6)}` : '—');
66
+ const bpsToPercent = (bps: number) => `${(bps / 100).toFixed(2)}%`;
67
+
68
+ function StatCard({
69
+ label,
70
+ value,
71
+ sub,
72
+ accent
73
+ }: {
74
+ label: string;
75
+ value: string;
76
+ sub?: string;
77
+ accent?: 'green' | 'amber' | 'red' | 'blue' | 'purple';
78
+ }) {
79
+ const colors: Record<string, string> = {
80
+ green: 'border-emerald-700/40 text-emerald-300',
81
+ amber: 'border-amber-700/40 text-amber-300',
82
+ red: 'border-red-700/40 text-red-300',
83
+ blue: 'border-blue-700/40 text-blue-300',
84
+ purple: 'border-purple-700/40 text-purple-300'
85
+ };
86
+ return (
87
+ <div
88
+ className={`rounded-xl border bg-black/30 p-4 ${
89
+ accent ? colors[accent] : 'border-white/10 text-white'
90
+ }`}
91
+ >
92
+ <p className="text-xs opacity-60 mb-1">{label}</p>
93
+ <p className="text-lg font-semibold">{value}</p>
94
+ {sub && <p className="text-xs opacity-50 mt-0.5">{sub}</p>}
95
+ </div>
96
+ );
97
+ }
98
+
99
+ function SectionTitle({ children }: { children: React.ReactNode }) {
100
+ return (
101
+ <h2 className="text-sm font-semibold text-white/40 uppercase tracking-widest mt-8 mb-3">
102
+ {children}
103
+ </h2>
104
+ );
105
+ }
106
+
107
+ // ── Page ──────────────────────────────────────────────────────────────────────
108
+
109
+ export default function AdminPage() {
110
+ const account = useCurrentAccount();
111
+ const { contract, graphqlClient, dappHubId, dappStorageId } = useDubhe();
112
+ const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();
113
+
114
+ const hubId = dappHubId ?? DappHubId;
115
+ const storageId = dappStorageId ?? DappStorageId;
116
+
117
+ const [feeState, setFeeState] = useState<FeeState | null>(null);
118
+ const [revenueState, setRevenueState] = useState<RevenueState | null>(null);
119
+ const [runtimeState, setRuntimeState] = useState<RuntimeState | null>(null);
120
+ const [marketplaceFees, setMarketplaceFees] = useState<MarketplaceFeeRecord[]>([]);
121
+ const [settlementHistory, setSettlementHistory] = useState<SettlementRecord[]>([]);
122
+ const [frameworkTreasury, setFrameworkTreasury] = useState<FrameworkTreasury | null>(null);
123
+ const [isLoading, setIsLoading] = useState(true);
124
+ const [isWithdrawing, setIsWithdrawing] = useState(false);
125
+
126
+ // ── Data fetching ──────────────────────────────────────────────────────────
127
+
128
+ const fetchData = useCallback(async () => {
129
+ if (!contract || !graphqlClient) return;
130
+ setIsLoading(true);
131
+ try {
132
+ // ── Chain: real-time DappStorage ──────────────────────────────────────
133
+ const fields = await contract.getDappStorageFields(storageId);
134
+ setFeeState({
135
+ baseFeePerWrite: fields.base_fee_per_write,
136
+ bytesFeePerByte: fields.bytes_fee_per_byte,
137
+ freeCredit: fields.free_credit,
138
+ creditPool: fields.credit_pool,
139
+ totalSettled: fields.total_settled,
140
+ settlementMode: fields.settlement_mode,
141
+ writeFeeDappShareBps: fields.write_fee_dapp_share_bps
142
+ });
143
+
144
+ // ── Chain: DApp revenue balance (dynamic field on DappStorage) ───────
145
+ // dapp_revenue is a dynamic_field keyed by DappRevenueKey<CoinType>,
146
+ // so getObject() cannot return it — use the dedicated SDK method.
147
+ const coinType = '0x2::sui::SUI';
148
+ const dappRevBalance = await contract.getDappRevenueBalance(storageId, coinType);
149
+ setRevenueState({ dappRevenue: dappRevBalance, coinType });
150
+
151
+ // ── Indexer: runtime state (admin, paused, last event) ────────────────
152
+ const rtNode = await graphqlClient.getDappRuntimeState();
153
+ if (rtNode) {
154
+ setRuntimeState({
155
+ admin: rtNode.admin ?? fields.admin ?? '',
156
+ paused: Boolean(rtNode.paused),
157
+ lastRuntimeEvent: rtNode.lastRuntimeEvent ?? '',
158
+ lastRuntimeActor: rtNode.lastRuntimeActor ?? '',
159
+ lastRuntimeAmount: rtNode.lastRuntimeAmount ?? '0'
160
+ });
161
+ } else {
162
+ setRuntimeState({
163
+ admin: fields.admin,
164
+ paused: fields.paused,
165
+ lastRuntimeEvent: '',
166
+ lastRuntimeActor: '',
167
+ lastRuntimeAmount: '0'
168
+ });
169
+ }
170
+
171
+ // ── Indexer: marketplace fee records ──────────────────────────────────
172
+ const mktResult = await graphqlClient.getDappMarketplaceFees({ first: 20 }).catch((err) => {
173
+ console.error('[admin] marketplace fees query error:', err);
174
+ return null;
175
+ });
176
+ setMarketplaceFees(
177
+ (mktResult?.edges ?? []).map((e: any) => ({
178
+ listingId: e.node.listingId ?? '',
179
+ coinType: e.node.coinType ?? '',
180
+ totalFee: BigInt(e.node.totalFee ?? 0),
181
+ treasuryAmount: BigInt(e.node.treasuryAmount ?? 0),
182
+ dappAmount: BigInt(e.node.dappAmount ?? 0),
183
+ updatedAtCheckpoint: e.node.updatedAtCheckpoint ?? ''
184
+ }))
185
+ );
186
+
187
+ // ── Framework Treasury: address + SUI balance ────────────────────────
188
+ // Treasury is a plain address; coins are transferred directly to it.
189
+ // There is no "pending" on-chain object — the balance IS the claimable amount.
190
+ try {
191
+ const hubFields = await contract.getDappHubFields(hubId);
192
+ if (
193
+ hubFields.treasury &&
194
+ hubFields.treasury !==
195
+ '0x0000000000000000000000000000000000000000000000000000000000000000'
196
+ ) {
197
+ const suiClient = (contract as any).suiInteractor?.currentClient;
198
+ const balResp = suiClient
199
+ ? await suiClient.getBalance({ owner: hubFields.treasury })
200
+ : null;
201
+ setFrameworkTreasury({
202
+ address: hubFields.treasury,
203
+ balance: BigInt(balResp?.totalBalance ?? 0)
204
+ });
205
+ }
206
+ } catch {
207
+ // best-effort
208
+ }
209
+
210
+ // ── Sui RPC: WritesSettled event history ──────────────────────────────
211
+ // The indexer only stores the latest event via UPSERT; full history
212
+ // comes from the SDK which wraps queryEvents directly.
213
+ try {
214
+ const events = await contract.queryWritesSettledEvents(30);
215
+ setSettlementHistory(
216
+ events.map((ev) => ({
217
+ digest: ev.txDigest,
218
+ account: ev.account,
219
+ writes: ev.writes,
220
+ paidCost: BigInt(ev.paidCost),
221
+ timestampMs: ev.timestampMs
222
+ }))
223
+ );
224
+ } catch (err) {
225
+ console.error('[admin] Settlement history error:', err);
226
+ }
227
+ } catch (err) {
228
+ console.error('admin fetchData error:', err);
229
+ toast.error('Failed to load admin data');
230
+ } finally {
231
+ setIsLoading(false);
232
+ }
233
+ }, [contract, graphqlClient, storageId]);
234
+
235
+ useEffect(() => {
236
+ if (contract && graphqlClient) fetchData();
237
+ }, [contract, graphqlClient, fetchData]);
238
+
239
+ // ── Withdraw ───────────────────────────────────────────────────────────────
240
+
241
+ const handleWithdraw = () => {
242
+ if (!contract || !account) return;
243
+ if (!revenueState || revenueState.dappRevenue === 0n) {
244
+ toast.error('No revenue to withdraw');
245
+ return;
246
+ }
247
+ setIsWithdrawing(true);
248
+ const tx = new Transaction();
249
+ tx.moveCall({
250
+ target: `${contract.frameworkPackageId}::dapp_system::withdraw_dapp_revenue`,
251
+ typeArguments: [contract.dappKey!, revenueState.coinType],
252
+ arguments: [tx.object(hubId), tx.object(storageId)]
253
+ });
254
+ signAndExecuteTransaction(
255
+ { transaction: (tx as any).serialize(), chain: `sui:${Network ?? 'testnet'}` },
256
+ {
257
+ onSuccess: (resp) => {
258
+ toast.success('Revenue withdrawn successfully', {
259
+ description: (
260
+ <a
261
+ href={
262
+ contract?.getTxExplorerUrl(resp.digest) ??
263
+ fallbackExplorerUrl(resp.digest, Network ?? 'testnet')
264
+ }
265
+ target="_blank"
266
+ rel="noopener noreferrer"
267
+ className="text-xs text-blue-400 hover:text-blue-300 underline mt-1 inline-block"
268
+ >
269
+ View TX ↗
270
+ </a>
271
+ )
272
+ });
273
+ setIsWithdrawing(false);
274
+ setTimeout(fetchData, 1500);
275
+ },
276
+ onError: (e) => {
277
+ toast.error(`Withdraw failed: ${e.message}`);
278
+ setIsWithdrawing(false);
279
+ }
280
+ }
281
+ );
282
+ };
283
+
284
+ // ── Computed values ────────────────────────────────────────────────────────
285
+
286
+ const shareBps = feeState?.writeFeeDappShareBps ?? 0;
287
+ // Framework treasury received = total_settled × (10000 - share_bps) / 10000
288
+ const frameworkReceived = feeState
289
+ ? (feeState.totalSettled * BigInt(10000 - shareBps)) / 10000n
290
+ : 0n;
291
+ // DApp accumulated from write fees = total_settled × share_bps / 10000
292
+ const dappWriteFeeAccum = feeState ? (feeState.totalSettled * BigInt(shareBps)) / 10000n : 0n;
293
+
294
+ const totalMarketTreasury = marketplaceFees.reduce((s, r) => s + r.treasuryAmount, 0n);
295
+ const totalMarketDapp = marketplaceFees.reduce((s, r) => s + r.dappAmount, 0n);
296
+
297
+ const settlementLabel = (mode: number) => (mode === 0 ? 'DAPP_SUBSIDIZES' : 'USER_PAYS');
298
+
299
+ // ── Render ─────────────────────────────────────────────────────────────────
300
+
301
+ return (
302
+ <div
303
+ className="min-h-screen p-4 md:p-8"
304
+ style={{ background: 'radial-gradient(ellipse at top, #1a2a3a 0%, #060c14 100%)' }}
305
+ >
306
+ {/* Header */}
307
+ <div className="flex items-center justify-between mb-8">
308
+ <div>
309
+ <h1 className="text-2xl font-bold text-white">Admin · Revenue</h1>
310
+ <p className="text-sm text-white/40 mt-0.5">Framework pool, DApp pool and fee records</p>
311
+ </div>
312
+ <div className="flex items-center gap-3">
313
+ <button
314
+ onClick={fetchData}
315
+ disabled={isLoading}
316
+ className="px-3 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 text-white text-sm transition-colors disabled:opacity-40"
317
+ >
318
+ {isLoading ? 'Loading…' : 'Refresh'}
319
+ </button>
320
+ <ConnectButton />
321
+ </div>
322
+ </div>
323
+
324
+ {!account ? (
325
+ <div className="text-center text-white/40 py-20">Connect wallet to view admin data</div>
326
+ ) : isLoading && !feeState ? (
327
+ <div className="text-center text-white/40 py-20">Loading…</div>
328
+ ) : (
329
+ <>
330
+ {/* ── Arena (game-specific) ──────────────────────────────────── */}
331
+ <ArenaPanel />
332
+
333
+ {/* ── Write Fee Overview ─────────────────────────────────────── */}
334
+ <SectionTitle>Write Fee Overview</SectionTitle>
335
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
336
+ <StatCard
337
+ label="Total Settled (cumulative)"
338
+ value={feeState ? formatMist(feeState.totalSettled) : '—'}
339
+ sub="All write fees charged to users"
340
+ accent="amber"
341
+ />
342
+ <StatCard
343
+ label="Framework Treasury Received"
344
+ value={formatMist(frameworkReceived)}
345
+ sub={`${bpsToPercent(10000 - shareBps)} of total settled`}
346
+ accent="blue"
347
+ />
348
+ <StatCard
349
+ label="DApp Write Fee Accumulated"
350
+ value={formatMist(dappWriteFeeAccum)}
351
+ sub={`${bpsToPercent(shareBps)} share — set by framework admin`}
352
+ accent={shareBps === 0 ? 'red' : 'green'}
353
+ />
354
+ <StatCard
355
+ label="Settlement Mode"
356
+ value={feeState ? settlementLabel(feeState.settlementMode) : '—'}
357
+ sub={
358
+ feeState?.settlementMode === 0
359
+ ? 'Operator pays from credit_pool'
360
+ : 'User pays per settlement'
361
+ }
362
+ />
363
+ </div>
364
+
365
+ {/* ── Framework Treasury ─────────────────────────────────────── */}
366
+ <SectionTitle>Framework Treasury</SectionTitle>
367
+ <div className="rounded-xl border border-blue-700/30 bg-blue-900/10 p-4 flex flex-col md:flex-row md:items-center gap-4">
368
+ <div className="flex-1 grid grid-cols-1 md:grid-cols-2 gap-3">
369
+ <div>
370
+ <p className="text-xs text-white/40 mb-1">Treasury Address</p>
371
+ {frameworkTreasury?.address ? (
372
+ <div className="flex items-center gap-2">
373
+ <span className="font-mono text-sm text-blue-300">
374
+ {shortAddr(frameworkTreasury.address)}
375
+ </span>
376
+ <button
377
+ onClick={() => {
378
+ navigator.clipboard.writeText(frameworkTreasury.address);
379
+ toast.success('Treasury address copied');
380
+ }}
381
+ title="Copy address"
382
+ className="text-blue-400/60 hover:text-blue-300 transition-colors"
383
+ >
384
+ <svg
385
+ xmlns="http://www.w3.org/2000/svg"
386
+ className="w-3.5 h-3.5"
387
+ viewBox="0 0 24 24"
388
+ fill="none"
389
+ stroke="currentColor"
390
+ strokeWidth="2"
391
+ strokeLinecap="round"
392
+ strokeLinejoin="round"
393
+ >
394
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
395
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
396
+ </svg>
397
+ </button>
398
+ </div>
399
+ ) : (
400
+ <span className="text-white/30 text-sm">Not configured</span>
401
+ )}
402
+ </div>
403
+ <div>
404
+ <p className="text-xs text-white/40 mb-1">Treasury Balance (current)</p>
405
+ <p className="text-lg font-semibold text-blue-300">
406
+ {frameworkTreasury ? formatMist(frameworkTreasury.balance) : '—'}
407
+ </p>
408
+ <p className="text-xs text-white/30 mt-0.5">
409
+ Coins are transferred directly to this address — no separate claim step needed.
410
+ </p>
411
+ </div>
412
+ </div>
413
+ </div>
414
+
415
+ {/* ── Credit Pool (DAPP_SUBSIDIZES) ───────────────────────────── */}
416
+ <SectionTitle>Credit Pool</SectionTitle>
417
+ <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
418
+ <StatCard
419
+ label="Credit Pool Balance"
420
+ value={feeState ? formatMist(feeState.creditPool) : '—'}
421
+ sub={
422
+ feeState?.settlementMode === 0
423
+ ? 'Active — deducted per settlement'
424
+ : 'Inactive in USER_PAYS mode'
425
+ }
426
+ accent={
427
+ feeState && feeState.settlementMode === 0 && feeState.creditPool < MIST_PER_SUI
428
+ ? 'red'
429
+ : 'green'
430
+ }
431
+ />
432
+ <StatCard
433
+ label="Free Credit"
434
+ value={feeState ? formatMist(feeState.freeCredit) : '—'}
435
+ sub="Framework-granted free quota"
436
+ accent="blue"
437
+ />
438
+ <StatCard
439
+ label="DApp Status"
440
+ value={runtimeState?.paused ? 'Paused' : 'Active'}
441
+ accent={runtimeState?.paused ? 'red' : 'green'}
442
+ />
443
+ </div>
444
+
445
+ {/* ── DApp Revenue Pool (USER_PAYS) ───────────────────────────── */}
446
+ <SectionTitle>DApp Revenue (USER_PAYS collected)</SectionTitle>
447
+ {shareBps === 0 && (
448
+ <div className="mb-3 rounded-lg border border-amber-700/40 bg-amber-900/20 px-4 py-2.5 text-sm text-amber-300">
449
+ ⚠️ <strong>write_fee_dapp_share_bps = 0%</strong> — 100% of write fees go to the
450
+ framework treasury. Contact the framework admin to increase your DApp revenue share.
451
+ </div>
452
+ )}
453
+ <div className="flex items-start gap-4">
454
+ <div className="flex-1 grid grid-cols-1 md:grid-cols-2 gap-3">
455
+ <StatCard
456
+ label="Withdrawable Revenue"
457
+ value={revenueState ? formatMist(revenueState.dappRevenue) : '0 SUI'}
458
+ sub={revenueState?.coinType ?? 'SUI'}
459
+ accent={revenueState && revenueState.dappRevenue > 0n ? 'green' : undefined}
460
+ />
461
+ <StatCard
462
+ label="DApp Admin"
463
+ value={runtimeState ? shortAddr(runtimeState.admin) : '—'}
464
+ sub="Revenue is sent to this address on withdrawal"
465
+ />
466
+ </div>
467
+ <button
468
+ onClick={handleWithdraw}
469
+ disabled={isWithdrawing || !revenueState || revenueState.dappRevenue === 0n}
470
+ className="px-5 py-3 rounded-xl bg-emerald-700 hover:bg-emerald-600 text-white font-semibold
471
+ disabled:opacity-40 disabled:cursor-not-allowed transition-colors whitespace-nowrap self-start"
472
+ >
473
+ {isWithdrawing ? 'Withdrawing…' : 'Withdraw Revenue'}
474
+ </button>
475
+ </div>
476
+
477
+ {/* ── Fee Configuration ───────────────────────────────────────── */}
478
+ <SectionTitle>Fee Configuration</SectionTitle>
479
+ <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
480
+ <StatCard
481
+ label="Base Fee / Write"
482
+ value={
483
+ feeState
484
+ ? feeState.baseFeePerWrite === 0n
485
+ ? 'Free'
486
+ : `${feeState.baseFeePerWrite.toLocaleString()} MIST`
487
+ : '—'
488
+ }
489
+ />
490
+ <StatCard
491
+ label="Bytes Fee / Byte"
492
+ value={
493
+ feeState
494
+ ? feeState.bytesFeePerByte === 0n
495
+ ? 'Free'
496
+ : `${feeState.bytesFeePerByte.toLocaleString()} MIST`
497
+ : '—'
498
+ }
499
+ />
500
+ <StatCard
501
+ label="DApp Write Fee Share"
502
+ value={bpsToPercent(shareBps)}
503
+ sub={`${shareBps} bps — framework admin controlled`}
504
+ accent={shareBps === 0 ? 'red' : 'green'}
505
+ />
506
+ </div>
507
+
508
+ {/* ── Settlement History (via Sui RPC) ────────────────────────── */}
509
+ <SectionTitle>Settlement History — last 30 (dubhe_events::WritesSettled)</SectionTitle>
510
+ {settlementHistory.length === 0 ? (
511
+ <p className="text-white/30 text-sm">No settlement records found.</p>
512
+ ) : (
513
+ <div className="rounded-xl border border-white/10 overflow-hidden">
514
+ <table className="w-full text-sm text-white/70">
515
+ <thead>
516
+ <tr className="bg-white/5 text-left">
517
+ <th className="px-4 py-2 font-medium text-white/40">Time</th>
518
+ <th className="px-4 py-2 font-medium text-white/40">Account</th>
519
+ <th className="px-4 py-2 font-medium text-white/40">Writes</th>
520
+ <th className="px-4 py-2 font-medium text-amber-400/60">Paid Cost</th>
521
+ <th className="px-4 py-2 font-medium text-blue-400/60">→ Treasury</th>
522
+ <th className="px-4 py-2 font-medium text-emerald-400/60">→ DApp</th>
523
+ <th className="px-4 py-2 font-medium text-white/40">Tx</th>
524
+ </tr>
525
+ </thead>
526
+ <tbody>
527
+ {settlementHistory.map((rec, i) => {
528
+ const toTreasury = (rec.paidCost * BigInt(10000 - shareBps)) / 10000n;
529
+ const toDapp = rec.paidCost - toTreasury;
530
+ return (
531
+ <tr
532
+ key={rec.digest + i}
533
+ className={`border-t border-white/5 ${
534
+ i % 2 === 0 ? '' : 'bg-white/[0.02]'
535
+ }`}
536
+ >
537
+ <td className="px-4 py-2 text-xs opacity-50">
538
+ {rec.timestampMs ? new Date(rec.timestampMs).toLocaleString() : '—'}
539
+ </td>
540
+ <td className="px-4 py-2 font-mono text-xs">{shortAddr(rec.account)}</td>
541
+ <td className="px-4 py-2">{rec.writes.toLocaleString()}</td>
542
+ <td className="px-4 py-2 text-amber-300">
543
+ {rec.paidCost === 0n ? 'free' : formatMist(rec.paidCost)}
544
+ </td>
545
+ <td className="px-4 py-2 text-blue-300">
546
+ {toTreasury === 0n ? '—' : formatMist(toTreasury)}
547
+ </td>
548
+ <td className="px-4 py-2 text-emerald-300">
549
+ {toDapp === 0n ? '—' : formatMist(toDapp)}
550
+ </td>
551
+ <td className="px-4 py-2 font-mono text-xs opacity-40">
552
+ {rec.digest ? rec.digest.slice(0, 8) + '…' : '—'}
553
+ </td>
554
+ </tr>
555
+ );
556
+ })}
557
+ </tbody>
558
+ </table>
559
+ </div>
560
+ )}
561
+
562
+ {/* ── Marketplace Fees ────────────────────────────────────────── */}
563
+ <SectionTitle>Marketplace Fees</SectionTitle>
564
+ {marketplaceFees.length === 0 ? (
565
+ <p className="text-white/30 text-sm">
566
+ No marketplace fee records yet. Fees are recorded only when a listing is purchased
567
+ (not on listing).
568
+ </p>
569
+ ) : (
570
+ <>
571
+ <div className="grid grid-cols-2 gap-3 mb-4">
572
+ <StatCard
573
+ label="DApp Total (last 20)"
574
+ value={formatMist(totalMarketDapp)}
575
+ accent="green"
576
+ />
577
+ <StatCard
578
+ label="Framework Treasury (last 20)"
579
+ value={formatMist(totalMarketTreasury)}
580
+ accent="blue"
581
+ />
582
+ </div>
583
+ <div className="rounded-xl border border-white/10 overflow-hidden">
584
+ <table className="w-full text-sm text-white/70">
585
+ <thead>
586
+ <tr className="bg-white/5 text-left">
587
+ <th className="px-4 py-2 font-medium text-white/40">Listing</th>
588
+ <th className="px-4 py-2 font-medium text-white/40">Total Fee</th>
589
+ <th className="px-4 py-2 font-medium text-emerald-400/60">DApp</th>
590
+ <th className="px-4 py-2 font-medium text-blue-400/60">Treasury</th>
591
+ <th className="px-4 py-2 font-medium text-white/40">Checkpoint</th>
592
+ </tr>
593
+ </thead>
594
+ <tbody>
595
+ {marketplaceFees.map((rec, i) => (
596
+ <tr
597
+ key={rec.listingId}
598
+ className={`border-t border-white/5 ${
599
+ i % 2 === 0 ? '' : 'bg-white/[0.02]'
600
+ }`}
601
+ >
602
+ <td className="px-4 py-2 font-mono text-xs">{shortAddr(rec.listingId)}</td>
603
+ <td className="px-4 py-2">{formatMist(rec.totalFee)}</td>
604
+ <td className="px-4 py-2 text-emerald-400">{formatMist(rec.dappAmount)}</td>
605
+ <td className="px-4 py-2 text-blue-400">
606
+ {formatMist(rec.treasuryAmount)}
607
+ </td>
608
+ <td className="px-4 py-2 font-mono text-xs opacity-50">
609
+ {rec.updatedAtCheckpoint}
610
+ </td>
611
+ </tr>
612
+ ))}
613
+ </tbody>
614
+ </table>
615
+ </div>
616
+ </>
617
+ )}
618
+ </>
619
+ )}
620
+ </div>
621
+ );
622
+ }