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