create-dubhe 1.2.0-pre.123 → 1.2.0-pre.125
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 +1 -1
- package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/dapp_key.move +16 -1
- package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/user_storage_init.move +6 -2
- package/templates/101/sui-template/packages/contracts/src/dubhe/Move.lock +0 -6
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move +16 -1
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +83 -42
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +2 -2
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move +1 -1
- 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/typed_scene_test.move +25 -9
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/user_storage_test.move +6 -6
- package/templates/contract/sui-template/src/dubhe/Move.lock +0 -6
- package/templates/contract/sui-template/src/dubhe/sources/codegen/dapp_key.move +16 -1
- package/templates/contract/sui-template/src/dubhe/sources/systems/dapp_system.move +83 -42
- package/templates/contract/sui-template/src/dubhe/sources/tests/fee_test.move +2 -2
- package/templates/contract/sui-template/src/dubhe/sources/tests/integration_test.move +1 -1
- package/templates/contract/sui-template/src/dubhe/sources/tests/scene_session_test.move +269 -0
- package/templates/contract/sui-template/src/dubhe/sources/tests/typed_scene_test.move +25 -9
- package/templates/contract/sui-template/src/dubhe/sources/tests/user_storage_test.move +6 -6
- package/templates/contract/sui-template/src/template/sources/codegen/dapp_key.move +16 -1
- package/templates/contract/sui-template/src/template/sources/codegen/user_storage_init.move +6 -2
- 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/docker-compose.yml +2 -5
- package/templates/nextjs/sui-farm/packages/client/src/app/admin/page.tsx +618 -0
- package/templates/nextjs/sui-farm/packages/client/src/app/components/ProxyCard.tsx +1 -4
- package/templates/nextjs/sui-farm/packages/client/src/app/market/page.tsx +4 -13
- package/templates/nextjs/sui-farm/packages/client/src/app/page.tsx +142 -91
- package/templates/nextjs/sui-farm/packages/client/src/app/providers.tsx +4 -7
- package/templates/nextjs/sui-farm/packages/contracts/Dockerfile +1 -1
- package/templates/nextjs/sui-farm/packages/contracts/src/counter/sources/codegen/user_storage_init.move +6 -2
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/dapp_key.move +16 -1
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/permits/world.move +12 -9
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/user_storage_init.move +6 -2
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/crow_system.move +1 -5
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/systems/world_system.move +1 -1
- package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/dapp_key.move +16 -1
- package/templates/nextjs/sui-template/packages/contracts/src/counter/sources/codegen/user_storage_init.move +6 -2
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.lock +0 -6
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move +16 -1
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +83 -42
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +2 -2
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move +1 -1
- 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/typed_scene_test.move +25 -9
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/user_storage_test.move +6 -6
- package/templates/nextjs/sui-farm/packages/client/src/app/hooks/useSessionKey.ts +0 -250
package/dist/cli.js
CHANGED
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin/cli.ts","../src/config/chains.ts","../package.json","../src/exists.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport glob from 'fast-glob';\nimport yargsInteractive from 'yargs-interactive';\nimport { CHAINS } from '../config/chains';\nimport packageJson from '../../package.json';\nimport { exists } from '../exists';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst cwd = process.cwd();\n\nconst init = async () => {\n // Prepare chain options\n const chainChoices = CHAINS.map(({ title, description, value }) => ({\n name: `${title} - ${description}`,\n value\n }));\n\n // Step 1: Choose project name and chain\n const firstStep = await yargsInteractive()\n .usage('$0 [args]')\n .interactive({\n interactive: { default: true },\n projectName: {\n describe: 'Name your project',\n type: 'input'\n },\n chain: {\n describe: 'Pick your chain',\n type: 'list',\n choices: chainChoices.map((c) => c.value)\n },\n dubheVersion: {\n describe: 'The version of Dubhe packages to use, defaults to latest',\n type: 'input',\n default: packageJson.version\n }\n });\n\n const { projectName, chain, dubheVersion } = firstStep;\n if (!projectName) throw new Error('No project name provided.');\n\n // Get available templates based on the selected chain\n const selectedChain = CHAINS.find((c) => c.value === chain);\n if (!selectedChain) {\n throw new Error('Invalid chain selection');\n }\n\n // Prepare platform options\n const platformChoices = selectedChain.supportedTemplates.map(({ title, description, value }) => ({\n name: `${title} - ${description}`,\n value\n }));\n\n // Step 2: Choose platform\n const secondStep = await yargsInteractive()\n .usage('$0 [args]')\n .interactive({\n interactive: { default: true },\n platform: {\n describe: 'Pick your platform',\n type: 'list',\n choices: platformChoices.map((c) => c.value)\n }\n });\n\n const { platform } = secondStep;\n\n const selectedTemplate = selectedChain.supportedTemplates.find((t) => t.value === platform);\n if (!selectedTemplate) {\n throw new Error('Invalid platform selection');\n }\n\n const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);\n const pkgManager = pkgInfo ? pkgInfo.name : 'npm';\n\n const sourceDir = path.join(\n __dirname,\n '..',\n 'templates',\n selectedTemplate.path.replace('{chain}', chain)\n );\n\n if (!(await exists(sourceDir))) {\n throw new Error(`Template directory not found: ${sourceDir}`);\n }\n\n const destDir = path.join(process.cwd(), projectName);\n if (await exists(destDir)) {\n throw new Error(`Target directory \"${destDir}\" already exists.`);\n }\n\n const files = await glob('**/*', { cwd: sourceDir, dot: true });\n\n for (const filename of files) {\n const sourceFile = path.join(sourceDir, filename);\n const destFile = path.join(destDir, filename);\n\n await fs.mkdir(path.dirname(destFile), { recursive: true });\n\n if (/package\\.json$/.test(sourceFile)) {\n const source = await fs.readFile(sourceFile, 'utf-8');\n await fs.writeFile(destFile, source.replaceAll(/{{dubhe-version}}/g, dubheVersion), 'utf-8');\n } else if (/\\.gitignore_$/.test(sourceFile)) {\n await fs.copyFile(sourceFile, destFile.replace(/_$/, ''));\n } else {\n await fs.copyFile(sourceFile, destFile);\n }\n }\n\n const cdProjectName = path.relative(cwd, destDir);\n\n const styles = {\n success: '\\x1b[32m%s\\x1b[0m',\n info: '\\x1b[36m%s\\x1b[0m',\n command: '\\x1b[33m%s\\x1b[0m',\n separator: '\\x1b[90m%s\\x1b[0m'\n };\n\n console.log('\\n' + '='.repeat(60));\n console.log(styles.success, '🎉 Project creation successful!');\n console.log(styles.info, `📁 Project location: ${destDir}`);\n console.log(styles.separator, '-'.repeat(60));\n console.log(styles.info, 'Next steps:\\n');\n\n if (destDir !== cwd) {\n console.log(\n styles.command,\n ` cd ${cdProjectName.includes(' ') ? `\"${cdProjectName}\"` : cdProjectName}`\n );\n }\n\n const actualTemplate = selectedTemplate.value;\n\n switch (actualTemplate) {\n case '101':\n case 'web':\n console.log(styles.command, ` ${pkgManager} install`);\n console.log(styles.command, ` ${pkgManager} dubhe doctor`);\n console.log(styles.command, ` ${pkgManager} run dev`);\n break;\n case 'contract':\n console.log(styles.command, ` ${pkgManager} install`);\n console.log(styles.command, ` ${pkgManager} dubhe doctor`);\n break;\n }\n\n console.log(styles.separator, '\\n' + '='.repeat(60) + '\\n');\n};\n\nfunction pkgFromUserAgent(userAgent: string | undefined) {\n if (!userAgent) return undefined;\n const pkgSpec = userAgent.split(' ')[0];\n const pkgSpecArr = pkgSpec.split('/');\n return {\n name: pkgSpecArr[0],\n version: pkgSpecArr[1]\n };\n}\n\ninit().catch((e) => {\n console.error(e);\n});\n","interface Template {\n title: string;\n description: string;\n value: string;\n path: string;\n}\n\ninterface Chain {\n title: string;\n description: string;\n value: string;\n supportedTemplates: Template[];\n}\n\nconst TEMPLATES = {\n QUICK_START: {\n title: '101',\n description: 'Quick start',\n value: '101',\n path: '101/{chain}-template'\n },\n WEB: {\n title: 'Web',\n description: 'Web template',\n value: 'web',\n path: 'nextjs/{chain}-template'\n },\n CONTRACT: {\n title: 'Contract',\n description: 'Contract template',\n value: 'contract',\n path: 'contract/{chain}-template'\n }\n} as const;\n\nexport const CHAINS: Chain[] = [\n {\n title: 'sui',\n description: 'Sui',\n value: 'sui',\n supportedTemplates: [TEMPLATES.QUICK_START, TEMPLATES.WEB, TEMPLATES.CONTRACT]\n },\n {\n title: 'aptos',\n description: 'Aptos',\n value: 'aptos',\n supportedTemplates: [TEMPLATES.QUICK_START, TEMPLATES.WEB, TEMPLATES.CONTRACT]\n },\n {\n title: 'rooch',\n description: 'Rooch',\n value: 'rooch',\n supportedTemplates: [TEMPLATES.QUICK_START]\n },\n {\n title: 'initia',\n description: 'Initia',\n value: 'initia',\n supportedTemplates: [TEMPLATES.QUICK_START]\n },\n {\n title: 'movement',\n description: 'Movement',\n value: 'movement',\n supportedTemplates: [TEMPLATES.QUICK_START]\n }\n];\n","{\n \"name\": \"create-dubhe\",\n \"version\": \"1.2.0-pre.123\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/0xobelisk/dubhe.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"team@obelisk.build\",\n \"type\": \"module\",\n \"bin\": \"bin/cli.js\",\n \"files\": [\n \"bin\",\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"pnpm run type-check && pnpm run build:js\",\n \"build:js\": \"tsup && pnpm run copy-templates\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"shx rm -rf dist\",\n \"cocos-js-build\": \"cd cocos-lib-builder && npm i && browserify aptos.js -p esmify > ../templates/cocos/aptos-template/assets/lib/dubhe.js && browserify sui.js -p esmify > ../templates/cocos/sui-template/assets/lib/dubhe.js\",\n \"copy-templates\": \"tsx ./scripts/copy-templates.ts\",\n \"dev\": \"tsup --watch\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"lint\": \"eslint . --ext .ts\",\n \"type-check\": \"tsc --noEmit\",\n \"validate\": \"pnpm format:check && pnpm lint && pnpm type-check\"\n },\n \"dependencies\": {\n \"browser-resolve\": \"^2.0.0\",\n \"browser-sync\": \"^2.29.3\",\n \"fast-glob\": \"^3.3.3\",\n \"yargs-interactive\": \"^3.0.1\"\n },\n \"devDependencies\": {\n \"@types/cross-spawn\": \"^6.0.2\",\n \"@types/minimist\": \"^1.2.2\",\n \"@types/prompts\": \"^2.4.3\",\n \"@types/yargs-interactive\": \"^2.1.6\",\n \"browserify\": \"^17.0.0\",\n \"cross-spawn\": \"^7.0.3\",\n \"eslint\": \"^9.0.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"esmify\": \"^2.1.1\",\n \"kolorist\": \"^1.7.0\",\n \"prettier\": \"3.3.3\",\n \"prompts\": \"^2.4.2\",\n \"typescript\": \"^5.8.3\"\n },\n \"engines\": {\n \"node\": \">=22.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import fs from 'node:fs/promises';\n\nexport async function exists(path: string) {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAC9B,OAAOA,SAAQ;AACf,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,sBAAsB;;;ACU7B,IAAM,YAAY;AAAA,EAChB,aAAa;AAAA,IACX,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AACF;AAEO,IAAM,SAAkB;AAAA,EAC7B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,oBAAoB,CAAC,UAAU,aAAa,UAAU,KAAK,UAAU,QAAQ;AAAA,EAC/E;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,oBAAoB,CAAC,UAAU,aAAa,UAAU,KAAK,UAAU,QAAQ;AAAA,EAC/E;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,oBAAoB,CAAC,UAAU,WAAW;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,oBAAoB,CAAC,UAAU,WAAW;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,IACP,oBAAoB,CAAC,UAAU,WAAW;AAAA,EAC5C;AACF;;;AClEA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,SAAW;AAAA,EACX,QAAU;AAAA,EACV,MAAQ;AAAA,EACR,KAAO;AAAA,EACP,OAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,YAAY;AAAA,IACZ,OAAS;AAAA,IACT,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,KAAO;AAAA,IACP,QAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,MAAQ;AAAA,IACR,cAAc;AAAA,IACd,UAAY;AAAA,EACd;AAAA,EACA,cAAgB;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,qBAAqB;AAAA,EACvB;AAAA,EACA,iBAAmB;AAAA,IACjB,sBAAsB;AAAA,IACtB,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,4BAA4B;AAAA,IAC5B,YAAc;AAAA,IACd,eAAe;AAAA,IACf,QAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B,QAAU;AAAA,IACV,UAAY;AAAA,IACZ,UAAY;AAAA,IACZ,SAAW;AAAA,IACX,YAAc;AAAA,EAChB;AAAA,EACA,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,eAAiB;AAAA,IACf,QAAU;AAAA,EACZ;AACF;;;ACzDA,OAAO,QAAQ;AAEf,eAAsB,OAAOC,OAAc;AACzC,MAAI;AACF,UAAM,GAAG,OAAOA,KAAI;AACpB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AHAA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAEzC,IAAM,MAAM,QAAQ,IAAI;AAExB,IAAM,OAAO,YAAY;AAEvB,QAAM,eAAe,OAAO,IAAI,CAAC,EAAE,OAAO,aAAa,MAAM,OAAO;AAAA,IAClE,MAAM,GAAG,KAAK,MAAM,WAAW;AAAA,IAC/B;AAAA,EACF,EAAE;AAGF,QAAM,YAAY,MAAM,iBAAiB,EACtC,MAAM,WAAW,EACjB,YAAY;AAAA,IACX,aAAa,EAAE,SAAS,KAAK;AAAA,IAC7B,aAAa;AAAA,MACX,UAAU;AAAA,MACV,MAAM;AAAA,IACR;AAAA,IACA,OAAO;AAAA,MACL,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS,aAAa,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IAC1C;AAAA,IACA,cAAc;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS,gBAAY;AAAA,IACvB;AAAA,EACF,CAAC;AAEH,QAAM,EAAE,aAAa,OAAO,aAAa,IAAI;AAC7C,MAAI,CAAC,YAAa,OAAM,IAAI,MAAM,2BAA2B;AAG7D,QAAM,gBAAgB,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AAC1D,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAGA,QAAM,kBAAkB,cAAc,mBAAmB,IAAI,CAAC,EAAE,OAAO,aAAa,MAAM,OAAO;AAAA,IAC/F,MAAM,GAAG,KAAK,MAAM,WAAW;AAAA,IAC/B;AAAA,EACF,EAAE;AAGF,QAAM,aAAa,MAAM,iBAAiB,EACvC,MAAM,WAAW,EACjB,YAAY;AAAA,IACX,aAAa,EAAE,SAAS,KAAK;AAAA,IAC7B,UAAU;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS,gBAAgB,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IAC7C;AAAA,EACF,CAAC;AAEH,QAAM,EAAE,SAAS,IAAI;AAErB,QAAM,mBAAmB,cAAc,mBAAmB,KAAK,CAAC,MAAM,EAAE,UAAU,QAAQ;AAC1F,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,UAAU,iBAAiB,QAAQ,IAAI,qBAAqB;AAClE,QAAM,aAAa,UAAU,QAAQ,OAAO;AAE5C,QAAM,YAAY,KAAK;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,KAAK,QAAQ,WAAW,KAAK;AAAA,EAChD;AAEA,MAAI,CAAE,MAAM,OAAO,SAAS,GAAI;AAC9B,UAAM,IAAI,MAAM,iCAAiC,SAAS,EAAE;AAAA,EAC9D;AAEA,QAAM,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,WAAW;AACpD,MAAI,MAAM,OAAO,OAAO,GAAG;AACzB,UAAM,IAAI,MAAM,qBAAqB,OAAO,mBAAmB;AAAA,EACjE;AAEA,QAAM,QAAQ,MAAM,KAAK,QAAQ,EAAE,KAAK,WAAW,KAAK,KAAK,CAAC;AAE9D,aAAW,YAAY,OAAO;AAC5B,UAAM,aAAa,KAAK,KAAK,WAAW,QAAQ;AAChD,UAAM,WAAW,KAAK,KAAK,SAAS,QAAQ;AAE5C,UAAMC,IAAG,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAE1D,QAAI,iBAAiB,KAAK,UAAU,GAAG;AACrC,YAAM,SAAS,MAAMA,IAAG,SAAS,YAAY,OAAO;AACpD,YAAMA,IAAG,UAAU,UAAU,OAAO,WAAW,sBAAsB,YAAY,GAAG,OAAO;AAAA,IAC7F,WAAW,gBAAgB,KAAK,UAAU,GAAG;AAC3C,YAAMA,IAAG,SAAS,YAAY,SAAS,QAAQ,MAAM,EAAE,CAAC;AAAA,IAC1D,OAAO;AACL,YAAMA,IAAG,SAAS,YAAY,QAAQ;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,gBAAgB,KAAK,SAAS,KAAK,OAAO;AAEhD,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAEA,UAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;AACjC,UAAQ,IAAI,OAAO,SAAS,wCAAiC;AAC7D,UAAQ,IAAI,OAAO,MAAM,+BAAwB,OAAO,EAAE;AAC1D,UAAQ,IAAI,OAAO,WAAW,IAAI,OAAO,EAAE,CAAC;AAC5C,UAAQ,IAAI,OAAO,MAAM,eAAe;AAExC,MAAI,YAAY,KAAK;AACnB,YAAQ;AAAA,MACN,OAAO;AAAA,MACP,QAAQ,cAAc,SAAS,GAAG,IAAI,IAAI,aAAa,MAAM,aAAa;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,iBAAiB,iBAAiB;AAExC,UAAQ,gBAAgB;AAAA,IACtB,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,UAAU;AACrD,cAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,eAAe;AAC1D,cAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,UAAU;AACrD;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,UAAU;AACrD,cAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,eAAe;AAC1D;AAAA,EACJ;AAEA,UAAQ,IAAI,OAAO,WAAW,OAAO,IAAI,OAAO,EAAE,IAAI,IAAI;AAC5D;AAEA,SAAS,iBAAiB,WAA+B;AACvD,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,UAAU,UAAU,MAAM,GAAG,EAAE,CAAC;AACtC,QAAM,aAAa,QAAQ,MAAM,GAAG;AACpC,SAAO;AAAA,IACL,MAAM,WAAW,CAAC;AAAA,IAClB,SAAS,WAAW,CAAC;AAAA,EACvB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,MAAM;AAClB,UAAQ,MAAM,CAAC;AACjB,CAAC;","names":["fs","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin/cli.ts","../src/config/chains.ts","../package.json","../src/exists.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport glob from 'fast-glob';\nimport yargsInteractive from 'yargs-interactive';\nimport { CHAINS } from '../config/chains';\nimport packageJson from '../../package.json';\nimport { exists } from '../exists';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nconst cwd = process.cwd();\n\nconst init = async () => {\n // Prepare chain options\n const chainChoices = CHAINS.map(({ title, description, value }) => ({\n name: `${title} - ${description}`,\n value\n }));\n\n // Step 1: Choose project name and chain\n const firstStep = await yargsInteractive()\n .usage('$0 [args]')\n .interactive({\n interactive: { default: true },\n projectName: {\n describe: 'Name your project',\n type: 'input'\n },\n chain: {\n describe: 'Pick your chain',\n type: 'list',\n choices: chainChoices.map((c) => c.value)\n },\n dubheVersion: {\n describe: 'The version of Dubhe packages to use, defaults to latest',\n type: 'input',\n default: packageJson.version\n }\n });\n\n const { projectName, chain, dubheVersion } = firstStep;\n if (!projectName) throw new Error('No project name provided.');\n\n // Get available templates based on the selected chain\n const selectedChain = CHAINS.find((c) => c.value === chain);\n if (!selectedChain) {\n throw new Error('Invalid chain selection');\n }\n\n // Prepare platform options\n const platformChoices = selectedChain.supportedTemplates.map(({ title, description, value }) => ({\n name: `${title} - ${description}`,\n value\n }));\n\n // Step 2: Choose platform\n const secondStep = await yargsInteractive()\n .usage('$0 [args]')\n .interactive({\n interactive: { default: true },\n platform: {\n describe: 'Pick your platform',\n type: 'list',\n choices: platformChoices.map((c) => c.value)\n }\n });\n\n const { platform } = secondStep;\n\n const selectedTemplate = selectedChain.supportedTemplates.find((t) => t.value === platform);\n if (!selectedTemplate) {\n throw new Error('Invalid platform selection');\n }\n\n const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);\n const pkgManager = pkgInfo ? pkgInfo.name : 'npm';\n\n const sourceDir = path.join(\n __dirname,\n '..',\n 'templates',\n selectedTemplate.path.replace('{chain}', chain)\n );\n\n if (!(await exists(sourceDir))) {\n throw new Error(`Template directory not found: ${sourceDir}`);\n }\n\n const destDir = path.join(process.cwd(), projectName);\n if (await exists(destDir)) {\n throw new Error(`Target directory \"${destDir}\" already exists.`);\n }\n\n const files = await glob('**/*', { cwd: sourceDir, dot: true });\n\n for (const filename of files) {\n const sourceFile = path.join(sourceDir, filename);\n const destFile = path.join(destDir, filename);\n\n await fs.mkdir(path.dirname(destFile), { recursive: true });\n\n if (/package\\.json$/.test(sourceFile)) {\n const source = await fs.readFile(sourceFile, 'utf-8');\n await fs.writeFile(destFile, source.replaceAll(/{{dubhe-version}}/g, dubheVersion), 'utf-8');\n } else if (/\\.gitignore_$/.test(sourceFile)) {\n await fs.copyFile(sourceFile, destFile.replace(/_$/, ''));\n } else {\n await fs.copyFile(sourceFile, destFile);\n }\n }\n\n const cdProjectName = path.relative(cwd, destDir);\n\n const styles = {\n success: '\\x1b[32m%s\\x1b[0m',\n info: '\\x1b[36m%s\\x1b[0m',\n command: '\\x1b[33m%s\\x1b[0m',\n separator: '\\x1b[90m%s\\x1b[0m'\n };\n\n console.log('\\n' + '='.repeat(60));\n console.log(styles.success, '🎉 Project creation successful!');\n console.log(styles.info, `📁 Project location: ${destDir}`);\n console.log(styles.separator, '-'.repeat(60));\n console.log(styles.info, 'Next steps:\\n');\n\n if (destDir !== cwd) {\n console.log(\n styles.command,\n ` cd ${cdProjectName.includes(' ') ? `\"${cdProjectName}\"` : cdProjectName}`\n );\n }\n\n const actualTemplate = selectedTemplate.value;\n\n switch (actualTemplate) {\n case '101':\n case 'web':\n console.log(styles.command, ` ${pkgManager} install`);\n console.log(styles.command, ` ${pkgManager} dubhe doctor`);\n console.log(styles.command, ` ${pkgManager} run dev`);\n break;\n case 'contract':\n console.log(styles.command, ` ${pkgManager} install`);\n console.log(styles.command, ` ${pkgManager} dubhe doctor`);\n break;\n }\n\n console.log(styles.separator, '\\n' + '='.repeat(60) + '\\n');\n};\n\nfunction pkgFromUserAgent(userAgent: string | undefined) {\n if (!userAgent) return undefined;\n const pkgSpec = userAgent.split(' ')[0];\n const pkgSpecArr = pkgSpec.split('/');\n return {\n name: pkgSpecArr[0],\n version: pkgSpecArr[1]\n };\n}\n\ninit().catch((e) => {\n console.error(e);\n});\n","interface Template {\n title: string;\n description: string;\n value: string;\n path: string;\n}\n\ninterface Chain {\n title: string;\n description: string;\n value: string;\n supportedTemplates: Template[];\n}\n\nconst TEMPLATES = {\n QUICK_START: {\n title: '101',\n description: 'Quick start',\n value: '101',\n path: '101/{chain}-template'\n },\n WEB: {\n title: 'Web',\n description: 'Web template',\n value: 'web',\n path: 'nextjs/{chain}-template'\n },\n CONTRACT: {\n title: 'Contract',\n description: 'Contract template',\n value: 'contract',\n path: 'contract/{chain}-template'\n }\n} as const;\n\nexport const CHAINS: Chain[] = [\n {\n title: 'sui',\n description: 'Sui',\n value: 'sui',\n supportedTemplates: [TEMPLATES.QUICK_START, TEMPLATES.WEB, TEMPLATES.CONTRACT]\n },\n {\n title: 'aptos',\n description: 'Aptos',\n value: 'aptos',\n supportedTemplates: [TEMPLATES.QUICK_START, TEMPLATES.WEB, TEMPLATES.CONTRACT]\n },\n {\n title: 'rooch',\n description: 'Rooch',\n value: 'rooch',\n supportedTemplates: [TEMPLATES.QUICK_START]\n },\n {\n title: 'initia',\n description: 'Initia',\n value: 'initia',\n supportedTemplates: [TEMPLATES.QUICK_START]\n },\n {\n title: 'movement',\n description: 'Movement',\n value: 'movement',\n supportedTemplates: [TEMPLATES.QUICK_START]\n }\n];\n","{\n \"name\": \"create-dubhe\",\n \"version\": \"1.2.0-pre.125\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/0xobelisk/dubhe.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"team@obelisk.build\",\n \"type\": \"module\",\n \"bin\": \"bin/cli.js\",\n \"files\": [\n \"bin\",\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"build\": \"pnpm run type-check && pnpm run build:js\",\n \"build:js\": \"tsup && pnpm run copy-templates\",\n \"clean\": \"pnpm run clean:js\",\n \"clean:js\": \"shx rm -rf dist\",\n \"cocos-js-build\": \"cd cocos-lib-builder && npm i && browserify aptos.js -p esmify > ../templates/cocos/aptos-template/assets/lib/dubhe.js && browserify sui.js -p esmify > ../templates/cocos/sui-template/assets/lib/dubhe.js\",\n \"copy-templates\": \"tsx ./scripts/copy-templates.ts\",\n \"dev\": \"tsup --watch\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"lint\": \"eslint . --ext .ts\",\n \"type-check\": \"tsc --noEmit\",\n \"validate\": \"pnpm format:check && pnpm lint && pnpm type-check\"\n },\n \"dependencies\": {\n \"browser-resolve\": \"^2.0.0\",\n \"browser-sync\": \"^2.29.3\",\n \"fast-glob\": \"^3.3.3\",\n \"yargs-interactive\": \"^3.0.1\"\n },\n \"devDependencies\": {\n \"@types/cross-spawn\": \"^6.0.2\",\n \"@types/minimist\": \"^1.2.2\",\n \"@types/prompts\": \"^2.4.3\",\n \"@types/yargs-interactive\": \"^2.1.6\",\n \"browserify\": \"^17.0.0\",\n \"cross-spawn\": \"^7.0.3\",\n \"eslint\": \"^9.0.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"esmify\": \"^2.1.1\",\n \"kolorist\": \"^1.7.0\",\n \"prettier\": \"3.3.3\",\n \"prompts\": \"^2.4.2\",\n \"typescript\": \"^5.8.3\"\n },\n \"engines\": {\n \"node\": \">=22.0.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import fs from 'node:fs/promises';\n\nexport async function exists(path: string) {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["fs","path","fs"]}
|
package/package.json
CHANGED
package/templates/101/sui-template/packages/contracts/src/counter/sources/codegen/dapp_key.move
CHANGED
|
@@ -8,10 +8,25 @@ module counter::dapp_key {
|
|
|
8
8
|
use sui::address;
|
|
9
9
|
use std::ascii::String;
|
|
10
10
|
|
|
11
|
-
///
|
|
11
|
+
/// DappKey — package-level authorization token for this DApp.
|
|
12
|
+
///
|
|
13
|
+
/// SECURITY: `new()` is intentionally `public(package)`.
|
|
14
|
+
/// Only code compiled into this package can construct a DappKey instance.
|
|
15
|
+
/// All framework write functions (`set_record`, `set_field`,
|
|
16
|
+
/// `take_record`, `create_user_storage`, …) require `_auth: DappKey`
|
|
17
|
+
/// as proof that the call originated from inside this package — an
|
|
18
|
+
/// external PTB cannot fabricate that proof.
|
|
19
|
+
///
|
|
20
|
+
/// NEVER change `new()` to `public`, and never accept a DappKey
|
|
21
|
+
/// value as a parameter from an external caller. Either mistake removes
|
|
22
|
+
/// every package-level access guard, allowing any PTB to write arbitrary
|
|
23
|
+
/// user data or register UserStorages without going through the DApp's
|
|
24
|
+
/// own entry functions.
|
|
12
25
|
|
|
13
26
|
public struct DappKey has copy, drop {}
|
|
14
27
|
|
|
28
|
+
/// Constructs an authorization token. Callable only from within this package.
|
|
29
|
+
/// Pass the result as `_auth` to any framework function that requires it.
|
|
15
30
|
public(package) fun new(): DappKey {
|
|
16
31
|
DappKey {}
|
|
17
32
|
}
|
|
@@ -6,17 +6,21 @@
|
|
|
6
6
|
module counter::user_storage_init {
|
|
7
7
|
use dubhe::dapp_service::{DappHub, DappStorage};
|
|
8
8
|
use dubhe::dapp_system;
|
|
9
|
+
use counter::dapp_key;
|
|
9
10
|
use counter::dapp_key::DappKey;
|
|
11
|
+
use counter::migrate;
|
|
10
12
|
|
|
11
13
|
/// Create a UserStorage for the transaction sender within this DApp.
|
|
12
14
|
/// Must be called once before the user can interact with any user-level resources.
|
|
13
|
-
/// Aborts if the DApp
|
|
15
|
+
/// Aborts if the DApp version does not match this package, the DApp is paused,
|
|
16
|
+
/// or the framework version has advanced.
|
|
14
17
|
#[allow(lint(public_entry))]
|
|
15
18
|
public entry fun init_user_storage(
|
|
16
19
|
dapp_hub: &DappHub,
|
|
17
20
|
dapp_storage: &mut DappStorage,
|
|
18
21
|
ctx: &mut TxContext,
|
|
19
22
|
) {
|
|
20
|
-
dapp_system::
|
|
23
|
+
dapp_system::ensure_latest_version<DappKey>(dapp_storage, migrate::on_chain_version());
|
|
24
|
+
dapp_system::create_user_storage(dapp_key::new(), dapp_hub, dapp_storage, ctx);
|
|
21
25
|
}
|
|
22
26
|
}
|
|
@@ -39,9 +39,3 @@ source = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-f
|
|
|
39
39
|
use_environment = "testnet"
|
|
40
40
|
manifest_digest = "7AFB66695545775FBFBB2D3078ADFD084244D5002392E837FDE21D9EA1C6D01C"
|
|
41
41
|
deps = { MoveStdlib = "MoveStdlib" }
|
|
42
|
-
|
|
43
|
-
[env.mainnet]
|
|
44
|
-
chain-id = "35834a8a"
|
|
45
|
-
original-published-id = "0xdd59a0e210585ec38da6d966d2936c7476b9e08b3cc2f785ca998d084bf24c81"
|
|
46
|
-
latest-published-id = "0xdd59a0e210585ec38da6d966d2936c7476b9e08b3cc2f785ca998d084bf24c81"
|
|
47
|
-
published-version = "1"
|
package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/dapp_key.move
CHANGED
|
@@ -8,10 +8,25 @@ module dubhe::dapp_key {
|
|
|
8
8
|
use sui::address;
|
|
9
9
|
use std::ascii::String;
|
|
10
10
|
|
|
11
|
-
///
|
|
11
|
+
/// DappKey — package-level authorization token for this DApp.
|
|
12
|
+
///
|
|
13
|
+
/// SECURITY: `new()` is intentionally `public(package)`.
|
|
14
|
+
/// Only code compiled into this package can construct a DappKey instance.
|
|
15
|
+
/// All framework write functions (`set_record`, `set_field`,
|
|
16
|
+
/// `take_record`, `create_user_storage`, …) require `_auth: DappKey`
|
|
17
|
+
/// as proof that the call originated from inside this package — an
|
|
18
|
+
/// external PTB cannot fabricate that proof.
|
|
19
|
+
///
|
|
20
|
+
/// NEVER change `new()` to `public`, and never accept a DappKey
|
|
21
|
+
/// value as a parameter from an external caller. Either mistake removes
|
|
22
|
+
/// every package-level access guard, allowing any PTB to write arbitrary
|
|
23
|
+
/// user data or register UserStorages without going through the DApp's
|
|
24
|
+
/// own entry functions.
|
|
12
25
|
|
|
13
26
|
public struct DappKey has copy, drop {}
|
|
14
27
|
|
|
28
|
+
/// Constructs an authorization token. Callable only from within this package.
|
|
29
|
+
/// Pass the result as `_auth` to any framework function that requires it.
|
|
15
30
|
public(package) fun new(): DappKey {
|
|
16
31
|
DappKey {}
|
|
17
32
|
}
|
package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move
CHANGED
|
@@ -147,6 +147,7 @@ public fun create_dapp<DappKey: copy + drop>(
|
|
|
147
147
|
/// canonical owner also cannot create a duplicate while their storage is held
|
|
148
148
|
/// by the proxy.
|
|
149
149
|
public fun create_user_storage<DappKey: copy + drop>(
|
|
150
|
+
_auth: DappKey,
|
|
150
151
|
dapp_hub: &DappHub,
|
|
151
152
|
dapp_storage: &mut DappStorage,
|
|
152
153
|
ctx: &mut TxContext,
|
|
@@ -277,9 +278,10 @@ public fun delete_field<DappKey: copy + drop>(
|
|
|
277
278
|
//
|
|
278
279
|
// Reactive writes allow one participant to modify another participant's UserStorage
|
|
279
280
|
// within a shared scene context. Four-layer security:
|
|
280
|
-
// 1. ctx.sender() must be from
|
|
281
|
-
//
|
|
282
|
-
//
|
|
281
|
+
// 1. ctx.sender() must be authorized to write `from` (canonical owner or its
|
|
282
|
+
// active session key — sessions are delegated proxies for in-scene actions)
|
|
283
|
+
// 2. from's canonical owner must be a registered scene participant
|
|
284
|
+
// 3. target's canonical owner must be a registered scene participant
|
|
283
285
|
// 4. scene must be active (not expired)
|
|
284
286
|
//
|
|
285
287
|
// Write fees are charged to the initiator (`from`) under the initiator-pays model.
|
|
@@ -303,8 +305,8 @@ public fun set_record_reactive<DappKey: copy + drop, PermType>(
|
|
|
303
305
|
let scene_id = dapp_service::scene_permit_id(permit);
|
|
304
306
|
let meta = dapp_service::scene_permit_meta(permit);
|
|
305
307
|
|
|
306
|
-
// 1. Sender must be
|
|
307
|
-
error::
|
|
308
|
+
// 1. Sender must be authorized to write `from` (canonical owner or active session key).
|
|
309
|
+
error::no_permission(dapp_service::is_write_authorized(from, ctx.sender(), ctx.epoch_timestamp_ms()));
|
|
308
310
|
// 2. Initiator must be a scene participant (O(1) DF lookup).
|
|
309
311
|
error::not_scene_participant(dapp_service::is_scene_participant(scene_id, dapp_service::canonical_owner(from)));
|
|
310
312
|
// 3. Target must be a scene participant (O(1) DF lookup).
|
|
@@ -342,7 +344,7 @@ public fun set_field_reactive<DappKey: copy + drop, PermType>(
|
|
|
342
344
|
let scene_id = dapp_service::scene_permit_id(permit);
|
|
343
345
|
let meta = dapp_service::scene_permit_meta(permit);
|
|
344
346
|
|
|
345
|
-
error::
|
|
347
|
+
error::no_permission(dapp_service::is_write_authorized(from, ctx.sender(), ctx.epoch_timestamp_ms()));
|
|
346
348
|
error::not_scene_participant(dapp_service::is_scene_participant(scene_id, dapp_service::canonical_owner(from)));
|
|
347
349
|
error::not_scene_participant(dapp_service::is_scene_participant(scene_id, dapp_service::canonical_owner(target)));
|
|
348
350
|
error::scene_expired(dapp_service::is_scene_active(meta, ctx.epoch_timestamp_ms()));
|
|
@@ -503,19 +505,27 @@ public fun remove_object_field<DappKey: copy + drop, ObjType, T: store + copy +
|
|
|
503
505
|
|
|
504
506
|
/// Remove and return a native-typed field from a permit-bound SceneStorage Bag.
|
|
505
507
|
/// Emits a Dubhe_Scene_DeleteField event so off-chain indexers stay in sync.
|
|
508
|
+
/// The caller identifies as `user_storage`'s canonical owner; the transaction may be
|
|
509
|
+
/// signed by the canonical owner or its active session key (is_write_authorized).
|
|
506
510
|
public fun remove_scene_field<DappKey: copy + drop, PermType, SceneType, T: store + copy + drop>(
|
|
507
|
-
_auth:
|
|
508
|
-
permit:
|
|
509
|
-
storage:
|
|
510
|
-
|
|
511
|
-
|
|
511
|
+
_auth: DappKey,
|
|
512
|
+
permit: &ScenePermit<PermType>,
|
|
513
|
+
storage: &mut SceneStorage<SceneType>,
|
|
514
|
+
user_storage: &UserStorage,
|
|
515
|
+
field_name: vector<u8>,
|
|
516
|
+
ctx: &TxContext,
|
|
512
517
|
): T {
|
|
513
518
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
514
519
|
error::dapp_key_mismatch(dapp_service::scene_storage_dapp_key(storage) == dapp_key_str);
|
|
515
520
|
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
521
|
+
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(user_storage) == dapp_key_str);
|
|
516
522
|
assert_scene_storage_bound_to_permit(permit, storage);
|
|
517
|
-
|
|
518
|
-
error::
|
|
523
|
+
let now_ms = ctx.epoch_timestamp_ms();
|
|
524
|
+
error::scene_expired(dapp_service::is_scene_active(dapp_service::scene_permit_meta(permit), now_ms));
|
|
525
|
+
error::no_permission(dapp_service::is_write_authorized(user_storage, ctx.sender(), now_ms));
|
|
526
|
+
error::not_scene_participant(dapp_service::is_participant_in_scene_permit(
|
|
527
|
+
permit, dapp_service::canonical_owner(user_storage)
|
|
528
|
+
));
|
|
519
529
|
|
|
520
530
|
let scene_type = *dapp_service::scene_storage_type(storage);
|
|
521
531
|
let scene_id = sui::object::uid_to_address(dapp_service::scene_storage_id(storage));
|
|
@@ -728,20 +738,28 @@ public fun share_scene_storage<DappKey: copy + drop, SceneType>(
|
|
|
728
738
|
}
|
|
729
739
|
|
|
730
740
|
/// Write a native-typed field into a permit-bound SceneStorage Bag and emit an event.
|
|
741
|
+
/// The caller identifies as `user_storage`'s canonical owner; the transaction may be
|
|
742
|
+
/// signed by the canonical owner or its active session key (is_write_authorized).
|
|
731
743
|
public fun set_scene_field<DappKey: copy + drop, PermType, SceneType, T: store + copy + drop>(
|
|
732
|
-
_auth:
|
|
733
|
-
permit:
|
|
734
|
-
storage:
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
744
|
+
_auth: DappKey,
|
|
745
|
+
permit: &ScenePermit<PermType>,
|
|
746
|
+
storage: &mut SceneStorage<SceneType>,
|
|
747
|
+
user_storage: &UserStorage,
|
|
748
|
+
field_name: vector<u8>,
|
|
749
|
+
value: T,
|
|
750
|
+
ctx: &TxContext,
|
|
738
751
|
) {
|
|
739
752
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
740
753
|
error::dapp_key_mismatch(dapp_service::scene_storage_dapp_key(storage) == dapp_key_str);
|
|
741
754
|
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
755
|
+
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(user_storage) == dapp_key_str);
|
|
742
756
|
assert_scene_storage_bound_to_permit(permit, storage);
|
|
743
|
-
|
|
744
|
-
error::
|
|
757
|
+
let now_ms = ctx.epoch_timestamp_ms();
|
|
758
|
+
error::scene_expired(dapp_service::is_scene_active(dapp_service::scene_permit_meta(permit), now_ms));
|
|
759
|
+
error::no_permission(dapp_service::is_write_authorized(user_storage, ctx.sender(), now_ms));
|
|
760
|
+
error::not_scene_participant(dapp_service::is_participant_in_scene_permit(
|
|
761
|
+
permit, dapp_service::canonical_owner(user_storage)
|
|
762
|
+
));
|
|
745
763
|
|
|
746
764
|
let event_bytes = sui::bcs::to_bytes(&value);
|
|
747
765
|
dapp_service::set_scene_field(storage, field_name, value);
|
|
@@ -828,19 +846,25 @@ public fun destroy_scene_permit<DappKey: copy + drop, PermType>(
|
|
|
828
846
|
}
|
|
829
847
|
|
|
830
848
|
/// Helper: accept a scene invitation for a ScenePermit-backed scene.
|
|
831
|
-
/// Moves
|
|
849
|
+
/// Moves the caller's canonical owner from the invitees list to confirmed
|
|
850
|
+
/// participants. The transaction may be signed by the canonical owner or its
|
|
851
|
+
/// active session key (is_write_authorized) — the registered identity is
|
|
852
|
+
/// always the canonical owner address.
|
|
832
853
|
/// Guards: scene must be active AND the invitation window must not have expired.
|
|
833
854
|
public fun accept_scene_permit_invitation<DappKey: copy + drop, PermType>(
|
|
834
|
-
_auth:
|
|
835
|
-
permit:
|
|
836
|
-
|
|
855
|
+
_auth: DappKey,
|
|
856
|
+
permit: &mut ScenePermit<PermType>,
|
|
857
|
+
user_storage: &UserStorage,
|
|
858
|
+
ctx: &TxContext,
|
|
837
859
|
) {
|
|
838
860
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
839
861
|
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
862
|
+
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(user_storage) == dapp_key_str);
|
|
840
863
|
|
|
841
864
|
// Check both permit activity and invitation window before mutating.
|
|
842
865
|
// The immutable borrow of `meta` is released at the end of this block.
|
|
843
866
|
let now_ms = ctx.epoch_timestamp_ms();
|
|
867
|
+
error::no_permission(dapp_service::is_write_authorized(user_storage, ctx.sender(), now_ms));
|
|
844
868
|
{
|
|
845
869
|
let meta = dapp_service::scene_permit_meta(permit);
|
|
846
870
|
error::scene_expired(dapp_service::is_scene_active(meta, now_ms));
|
|
@@ -850,54 +874,71 @@ public fun accept_scene_permit_invitation<DappKey: copy + drop, PermType>(
|
|
|
850
874
|
};
|
|
851
875
|
};
|
|
852
876
|
|
|
853
|
-
dapp_service::
|
|
877
|
+
let owner = dapp_service::canonical_owner(user_storage);
|
|
878
|
+
dapp_service::accept_invitation_in_scene_permit(permit, owner);
|
|
854
879
|
dubhe_events::emit_scene_permit_accept(
|
|
855
880
|
dapp_key_str,
|
|
856
881
|
*dapp_service::scene_permit_type(permit),
|
|
857
882
|
sui::object::uid_to_address(dapp_service::scene_permit_id(permit)),
|
|
858
|
-
|
|
883
|
+
owner,
|
|
859
884
|
);
|
|
860
885
|
}
|
|
861
886
|
|
|
862
|
-
/// Helper: add the caller as a confirmed participant in a
|
|
887
|
+
/// Helper: add the caller's canonical owner as a confirmed participant in a
|
|
888
|
+
/// ScenePermit. The transaction may be signed by the canonical owner or its
|
|
889
|
+
/// active session key (is_write_authorized) — the registered identity is
|
|
890
|
+
/// always the canonical owner address.
|
|
863
891
|
/// The permit must still be active — joining an expired permit is meaningless and
|
|
864
892
|
/// wastes gas on a DF write that can never be used for reactive writes.
|
|
865
893
|
public fun join_scene_permit<DappKey: copy + drop, PermType>(
|
|
866
|
-
_auth:
|
|
867
|
-
permit:
|
|
868
|
-
|
|
894
|
+
_auth: DappKey,
|
|
895
|
+
permit: &mut ScenePermit<PermType>,
|
|
896
|
+
user_storage: &UserStorage,
|
|
897
|
+
ctx: &TxContext,
|
|
869
898
|
) {
|
|
870
899
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
871
900
|
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
872
|
-
error::
|
|
873
|
-
let
|
|
874
|
-
dapp_service::
|
|
901
|
+
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(user_storage) == dapp_key_str);
|
|
902
|
+
let now_ms = ctx.epoch_timestamp_ms();
|
|
903
|
+
error::scene_expired(dapp_service::is_scene_active(dapp_service::scene_permit_meta(permit), now_ms));
|
|
904
|
+
error::no_permission(dapp_service::is_write_authorized(user_storage, ctx.sender(), now_ms));
|
|
905
|
+
let owner = dapp_service::canonical_owner(user_storage);
|
|
906
|
+
let was_participant = dapp_service::is_participant_in_scene_permit(permit, owner);
|
|
907
|
+
dapp_service::add_participant_in_scene_permit(permit, owner);
|
|
875
908
|
if (!was_participant) {
|
|
876
909
|
dubhe_events::emit_scene_permit_join(
|
|
877
910
|
dapp_key_str,
|
|
878
911
|
*dapp_service::scene_permit_type(permit),
|
|
879
912
|
sui::object::uid_to_address(dapp_service::scene_permit_id(permit)),
|
|
880
|
-
|
|
913
|
+
owner,
|
|
881
914
|
);
|
|
882
915
|
};
|
|
883
916
|
}
|
|
884
917
|
|
|
885
|
-
/// Helper: remove the caller from participants in a
|
|
918
|
+
/// Helper: remove the caller's canonical owner from participants in a
|
|
919
|
+
/// SceneStorage scene. The transaction may be signed by the canonical owner or
|
|
920
|
+
/// its active session key (is_write_authorized).
|
|
886
921
|
public fun leave_scene_permit<DappKey: copy + drop, PermType>(
|
|
887
|
-
_auth:
|
|
888
|
-
permit:
|
|
889
|
-
|
|
922
|
+
_auth: DappKey,
|
|
923
|
+
permit: &mut ScenePermit<PermType>,
|
|
924
|
+
user_storage: &UserStorage,
|
|
925
|
+
ctx: &TxContext,
|
|
890
926
|
) {
|
|
891
927
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
892
928
|
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
893
|
-
|
|
894
|
-
dapp_service::
|
|
929
|
+
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(user_storage) == dapp_key_str);
|
|
930
|
+
error::no_permission(dapp_service::is_write_authorized(
|
|
931
|
+
user_storage, ctx.sender(), ctx.epoch_timestamp_ms()
|
|
932
|
+
));
|
|
933
|
+
let owner = dapp_service::canonical_owner(user_storage);
|
|
934
|
+
let was_participant = dapp_service::is_participant_in_scene_permit(permit, owner);
|
|
935
|
+
dapp_service::remove_participant_in_scene_permit(permit, owner);
|
|
895
936
|
if (was_participant) {
|
|
896
937
|
dubhe_events::emit_scene_permit_leave(
|
|
897
938
|
dapp_key_str,
|
|
898
939
|
*dapp_service::scene_permit_type(permit),
|
|
899
940
|
sui::object::uid_to_address(dapp_service::scene_permit_id(permit)),
|
|
900
|
-
|
|
941
|
+
owner,
|
|
901
942
|
);
|
|
902
943
|
};
|
|
903
944
|
}
|
|
@@ -700,7 +700,7 @@ fun test_create_user_storage_succeeds_at_correct_version() {
|
|
|
700
700
|
// Framework version == FRAMEWORK_VERSION (1) — must succeed.
|
|
701
701
|
assert!(dapp_service::framework_version(&dh) == dapp_system::framework_version());
|
|
702
702
|
|
|
703
|
-
dapp_system::create_user_storage
|
|
703
|
+
dapp_system::create_user_storage(FeeKey {}, &dh, &mut ds, ctx);
|
|
704
704
|
assert!(dapp_service::has_registered_user_storage(&ds, sender));
|
|
705
705
|
|
|
706
706
|
dapp_system::destroy_dapp_hub(dh);
|
|
@@ -753,7 +753,7 @@ fun test_create_user_storage_aborts_after_framework_version_bump() {
|
|
|
753
753
|
dapp_service::set_framework_version(&mut dh, 2);
|
|
754
754
|
|
|
755
755
|
// This package still has FRAMEWORK_VERSION = 1, so the call must abort.
|
|
756
|
-
dapp_system::create_user_storage
|
|
756
|
+
dapp_system::create_user_storage(FeeKey {}, &dh, &mut ds, ctx);
|
|
757
757
|
|
|
758
758
|
dapp_system::destroy_dapp_hub(dh);
|
|
759
759
|
dapp_system::destroy_dapp_storage(ds);
|
package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/integration_test.move
CHANGED
|
@@ -251,7 +251,7 @@ fun test_user_can_always_create_storage() {
|
|
|
251
251
|
test_scenario::next_tx(&mut scenario, USER_A);
|
|
252
252
|
{
|
|
253
253
|
let ctx = test_scenario::ctx(&mut scenario);
|
|
254
|
-
dapp_system::create_user_storage
|
|
254
|
+
dapp_system::create_user_storage(GameKey {}, &dh, &mut ds, ctx);
|
|
255
255
|
assert!(dapp_service::has_registered_user_storage(&ds, USER_A));
|
|
256
256
|
};
|
|
257
257
|
|