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