create-dubhe 1.2.0-pre.121 → 1.2.0-pre.123
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/dubhe/Move.lock +2 -2
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/codegen/error.move +0 -16
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move +51 -35
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +30 -135
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +3 -3
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/listing_test.move +128 -0
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/typed_object_test.move +33 -0
- package/templates/101/sui-template/packages/contracts/src/dubhe/sources/tests/typed_scene_test.move +151 -157
- package/templates/contract/sui-template/src/dubhe/Move.lock +2 -2
- package/templates/contract/sui-template/src/dubhe/sources/codegen/error.move +0 -16
- package/templates/contract/sui-template/src/dubhe/sources/core/dapp_service.move +51 -35
- package/templates/contract/sui-template/src/dubhe/sources/systems/dapp_system.move +30 -135
- package/templates/contract/sui-template/src/dubhe/sources/tests/fee_test.move +3 -3
- package/templates/contract/sui-template/src/dubhe/sources/tests/listing_test.move +128 -0
- package/templates/contract/sui-template/src/dubhe/sources/tests/typed_object_test.move +33 -0
- package/templates/contract/sui-template/src/dubhe/sources/tests/typed_scene_test.move +151 -157
- package/templates/nextjs/sui-farm/packages/contracts/src/harvest/sources/codegen/resources/crow_damage.move +10 -12
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/Move.lock +2 -2
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/codegen/error.move +0 -16
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move +51 -35
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move +30 -135
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/fee_test.move +3 -3
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/listing_test.move +128 -0
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_object_test.move +33 -0
- package/templates/nextjs/sui-template/packages/contracts/src/dubhe/sources/tests/typed_scene_test.move +151 -157
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.121\",\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"]}
|
|
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":"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","names":["fs","path","fs"]}
|
package/package.json
CHANGED
|
@@ -42,6 +42,6 @@ deps = { MoveStdlib = "MoveStdlib" }
|
|
|
42
42
|
|
|
43
43
|
[env.mainnet]
|
|
44
44
|
chain-id = "35834a8a"
|
|
45
|
-
original-published-id = "
|
|
46
|
-
latest-published-id = "
|
|
45
|
+
original-published-id = "0xdd59a0e210585ec38da6d966d2936c7476b9e08b3cc2f785ca998d084bf24c81"
|
|
46
|
+
latest-published-id = "0xdd59a0e210585ec38da6d966d2936c7476b9e08b3cc2f785ca998d084bf24c81"
|
|
47
47
|
published-version = "1"
|
|
@@ -40,10 +40,6 @@ module dubhe::error {
|
|
|
40
40
|
const EUserDebtLimitExceeded: vector<u8> = b"User debt limit exceeded";
|
|
41
41
|
public fun user_debt_limit_exceeded(condition: bool) { assert!(condition, EUserDebtLimitExceeded) }
|
|
42
42
|
|
|
43
|
-
#[error]
|
|
44
|
-
const EDappSuspended: vector<u8> = b"Dapp is suspended";
|
|
45
|
-
public fun dapp_suspended(condition: bool) { assert!(condition, EDappSuspended) }
|
|
46
|
-
|
|
47
43
|
#[error]
|
|
48
44
|
const EDappKeyMismatch: vector<u8> = b"Dapp key mismatch";
|
|
49
45
|
public fun dapp_key_mismatch(condition: bool) { assert!(condition, EDappKeyMismatch) }
|
|
@@ -56,10 +52,6 @@ module dubhe::error {
|
|
|
56
52
|
const ENotCanonicalOwner: vector<u8> = b"Not canonical owner";
|
|
57
53
|
public fun not_canonical_owner(condition: bool) { assert!(condition, ENotCanonicalOwner) }
|
|
58
54
|
|
|
59
|
-
#[error]
|
|
60
|
-
const EInsufficientCreditToUnsuspend: vector<u8> = b"Insufficient credit to unsuspend";
|
|
61
|
-
public fun insufficient_credit_to_unsuspend(condition: bool) { assert!(condition, EInsufficientCreditToUnsuspend) }
|
|
62
|
-
|
|
63
55
|
#[error]
|
|
64
56
|
const EUserStorageAlreadyExists: vector<u8> = b"User storage already exists";
|
|
65
57
|
public fun user_storage_already_exists(condition: bool) { assert!(condition, EUserStorageAlreadyExists) }
|
|
@@ -104,14 +96,6 @@ module dubhe::error {
|
|
|
104
96
|
const ENotSceneParticipant: vector<u8> = b"Not a scene participant";
|
|
105
97
|
public fun not_scene_participant(condition: bool) { assert!(condition, ENotSceneParticipant) }
|
|
106
98
|
|
|
107
|
-
#[error]
|
|
108
|
-
const ENonceAlreadyUsed: vector<u8> = b"Nonce already used";
|
|
109
|
-
public fun nonce_already_used(condition: bool) { assert!(condition, ENonceAlreadyUsed) }
|
|
110
|
-
|
|
111
|
-
#[error]
|
|
112
|
-
const EInvalidConsentSignature: vector<u8> = b"Invalid consent signature";
|
|
113
|
-
public fun invalid_consent_signature(condition: bool) { assert!(condition, EInvalidConsentSignature) }
|
|
114
|
-
|
|
115
99
|
#[error]
|
|
116
100
|
const EEntityNotFound: vector<u8> = b"Entity not found";
|
|
117
101
|
public fun entity_not_found(condition: bool) { assert!(condition, EEntityNotFound) }
|
package/templates/101/sui-template/packages/contracts/src/dubhe/sources/core/dapp_service.move
CHANGED
|
@@ -33,9 +33,9 @@ module dubhe::dapp_service {
|
|
|
33
33
|
// ─── PermitMetadata — authorization token for reactive writes ─────────────
|
|
34
34
|
//
|
|
35
35
|
// Embedded in every codegen-generated typed SceneStorage struct.
|
|
36
|
-
// Reactive write functions require a
|
|
37
|
-
//
|
|
38
|
-
//
|
|
36
|
+
// Reactive write functions require a &ScenePermit<T> to verify that both
|
|
37
|
+
// the initiator and the target are registered participants and that the
|
|
38
|
+
// scene is still active.
|
|
39
39
|
//
|
|
40
40
|
// Participants are stored as dynamic fields on the scene object's UID
|
|
41
41
|
// (key = ParticipantKey { addr }, value = bool true). This gives O(1)
|
|
@@ -56,7 +56,7 @@ module dubhe::dapp_service {
|
|
|
56
56
|
/// None = invitations never expire. Once passed, accept_<scene> aborts.
|
|
57
57
|
invites_expire_at: Option<u64>,
|
|
58
58
|
/// Maximum number of confirmed participants allowed in this scene.
|
|
59
|
-
/// None = unlimited. Enforced
|
|
59
|
+
/// None = unlimited. Enforced on participant add.
|
|
60
60
|
max_participants: Option<u64>,
|
|
61
61
|
/// Current confirmed participant count — updated by add/remove.
|
|
62
62
|
participant_count: u64,
|
|
@@ -114,36 +114,6 @@ module dubhe::dapp_service {
|
|
|
114
114
|
meta.invitees.contains(&addr)
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
/// Moves `addr` from the invitees list into the confirmed participants list.
|
|
118
|
-
/// Aborts if addr is not in invitees.
|
|
119
|
-
public fun accept_scene_invitation_meta(id: &mut UID, meta: &mut PermitMetadata, addr: address) {
|
|
120
|
-
let (found, idx) = meta.invitees.index_of(&addr);
|
|
121
|
-
error::not_participant(found);
|
|
122
|
-
meta.invitees.remove(idx);
|
|
123
|
-
add_scene_participant(id, meta, addr);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/// Add `addr` as a confirmed participant (O(1) dynamic field write).
|
|
127
|
-
/// Enforces max_participants cap if set. No-op if already a participant.
|
|
128
|
-
public fun add_scene_participant(id: &mut UID, meta: &mut PermitMetadata, addr: address) {
|
|
129
|
-
if (dynamic_field::exists_(id, ParticipantKey { addr })) { return };
|
|
130
|
-
if (meta.max_participants.is_some()) {
|
|
131
|
-
error::scene_full(
|
|
132
|
-
meta.participant_count < *option::borrow(&meta.max_participants)
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
dynamic_field::add(id, ParticipantKey { addr }, true);
|
|
136
|
-
meta.participant_count = meta.participant_count + 1;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/// Remove `addr` from confirmed participants (O(1) dynamic field remove).
|
|
140
|
-
/// No-op if not a participant.
|
|
141
|
-
public fun remove_scene_participant(id: &mut UID, meta: &mut PermitMetadata, addr: address) {
|
|
142
|
-
if (!dynamic_field::exists_(id, ParticipantKey { addr })) { return };
|
|
143
|
-
let _: bool = dynamic_field::remove(id, ParticipantKey { addr });
|
|
144
|
-
meta.participant_count = meta.participant_count - 1;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
117
|
/// O(1) participant check via dynamic field existence.
|
|
148
118
|
public fun is_scene_participant(id: &UID, addr: address): bool {
|
|
149
119
|
dynamic_field::exists_(id, ParticipantKey { addr })
|
|
@@ -189,6 +159,7 @@ module dubhe::dapp_service {
|
|
|
189
159
|
};
|
|
190
160
|
}
|
|
191
161
|
|
|
162
|
+
#[test_only]
|
|
192
163
|
public fun has_object_entity_id(
|
|
193
164
|
ds: &DappStorage,
|
|
194
165
|
type_tag: vector<u8>,
|
|
@@ -197,6 +168,7 @@ module dubhe::dapp_service {
|
|
|
197
168
|
dynamic_field::exists_(&ds.id, ObjectEntityIdKey { type_tag, entity_id })
|
|
198
169
|
}
|
|
199
170
|
|
|
171
|
+
#[test_only]
|
|
200
172
|
public fun get_object_entity_id(
|
|
201
173
|
ds: &DappStorage,
|
|
202
174
|
type_tag: vector<u8>,
|
|
@@ -535,7 +507,7 @@ module dubhe::dapp_service {
|
|
|
535
507
|
let mut i = 0;
|
|
536
508
|
let len = participants.length();
|
|
537
509
|
while (i < len) {
|
|
538
|
-
|
|
510
|
+
add_participant_in_scene_permit(&mut permit, *participants.borrow(i));
|
|
539
511
|
i = i + 1;
|
|
540
512
|
};
|
|
541
513
|
let permit_id = object::uid_to_address(&permit.id);
|
|
@@ -933,11 +905,17 @@ module dubhe::dapp_service {
|
|
|
933
905
|
};
|
|
934
906
|
}
|
|
935
907
|
|
|
908
|
+
/// Return the full fee-change history ring buffer (most recent at the back).
|
|
909
|
+
/// Useful for off-chain explorers and billing tools that need to determine
|
|
910
|
+
/// the applicable fee rate for a historical write operation.
|
|
936
911
|
public fun fee_history(cfg: &FrameworkFeeConfig): &vector<FeeHistoryEntry> {
|
|
937
912
|
&cfg.fee_history
|
|
938
913
|
}
|
|
914
|
+
/// Base fee that was committed in this history entry (MIST per write).
|
|
939
915
|
public fun fee_history_base_fee(e: &FeeHistoryEntry): u256 { e.base_fee }
|
|
916
|
+
/// Bytes fee that was committed in this history entry (MIST per byte).
|
|
940
917
|
public fun fee_history_bytes_fee(e: &FeeHistoryEntry): u256 { e.bytes_fee }
|
|
918
|
+
/// Epoch-ms timestamp from which this history entry's rates became effective.
|
|
941
919
|
public fun fee_history_effective_from_ms(e: &FeeHistoryEntry): u64 { e.effective_from_ms }
|
|
942
920
|
|
|
943
921
|
public fun is_fee_config_initialized(dh: &DappHub): bool {
|
|
@@ -1823,4 +1801,42 @@ module dubhe::dapp_service {
|
|
|
1823
1801
|
object::delete(id);
|
|
1824
1802
|
}
|
|
1825
1803
|
|
|
1804
|
+
#[test_only]
|
|
1805
|
+
public fun create_scene_permit_for_testing<DappKey: copy + drop, PermType>(
|
|
1806
|
+
participants: vector<address>,
|
|
1807
|
+
expires_at: std::option::Option<u64>,
|
|
1808
|
+
max_participants: std::option::Option<u64>,
|
|
1809
|
+
ctx: &mut TxContext,
|
|
1810
|
+
): ScenePermit<PermType> {
|
|
1811
|
+
let mut permit = ScenePermit<PermType> {
|
|
1812
|
+
id: object::new(ctx),
|
|
1813
|
+
dapp_key: type_name::with_defining_ids<DappKey>().into_string(),
|
|
1814
|
+
permit_type: b"test",
|
|
1815
|
+
meta: new_scene_meta(expires_at, max_participants),
|
|
1816
|
+
};
|
|
1817
|
+
participants.do!(|addr| { add_participant_in_scene_permit(&mut permit, addr) });
|
|
1818
|
+
permit
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
#[test_only]
|
|
1822
|
+
public fun create_scene_permit_with_invitations_for_testing<DappKey: copy + drop, PermType>(
|
|
1823
|
+
invitees: vector<address>,
|
|
1824
|
+
invites_expire_at: std::option::Option<u64>,
|
|
1825
|
+
expires_at: std::option::Option<u64>,
|
|
1826
|
+
ctx: &mut TxContext,
|
|
1827
|
+
): ScenePermit<PermType> {
|
|
1828
|
+
ScenePermit<PermType> {
|
|
1829
|
+
id: object::new(ctx),
|
|
1830
|
+
dapp_key: type_name::with_defining_ids<DappKey>().into_string(),
|
|
1831
|
+
permit_type: b"test",
|
|
1832
|
+
meta: new_scene_meta_with_invitations(invitees, invites_expire_at, expires_at, option::none()),
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
#[test_only]
|
|
1837
|
+
public fun destroy_scene_permit_for_testing<PermType>(permit: ScenePermit<PermType>) {
|
|
1838
|
+
let ScenePermit { id, dapp_key: _, permit_type: _, meta: _ } = permit;
|
|
1839
|
+
object::delete(id);
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1826
1842
|
}
|
package/templates/101/sui-template/packages/contracts/src/dubhe/sources/systems/dapp_system.move
CHANGED
|
@@ -152,12 +152,13 @@ public fun create_user_storage<DappKey: copy + drop>(
|
|
|
152
152
|
ctx: &mut TxContext,
|
|
153
153
|
) {
|
|
154
154
|
assert_framework_version(dapp_hub);
|
|
155
|
+
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
156
|
+
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
155
157
|
error::dapp_paused(!dapp_service::dapp_paused(dapp_storage));
|
|
156
158
|
let sender = ctx.sender();
|
|
157
159
|
error::user_storage_already_exists(!dapp_service::has_registered_user_storage(dapp_storage, sender));
|
|
158
160
|
dapp_service::register_user_storage(dapp_storage, sender);
|
|
159
161
|
let write_limit = dapp_service::framework_max_write_limit(dapp_service::get_config(dapp_hub));
|
|
160
|
-
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
161
162
|
let us = dapp_service::new_user_storage<DappKey>(sender, write_limit, ctx);
|
|
162
163
|
dubhe_events::emit_user_storage_created(
|
|
163
164
|
dapp_key_str,
|
|
@@ -283,11 +284,10 @@ public fun delete_field<DappKey: copy + drop>(
|
|
|
283
284
|
//
|
|
284
285
|
// Write fees are charged to the initiator (`from`) under the initiator-pays model.
|
|
285
286
|
|
|
286
|
-
/// Write a full record to another user's UserStorage, authorized by
|
|
287
|
-
public fun set_record_reactive<DappKey: copy + drop>(
|
|
287
|
+
/// Write a full record to another user's UserStorage, authorized by a ScenePermit.
|
|
288
|
+
public fun set_record_reactive<DappKey: copy + drop, PermType>(
|
|
288
289
|
_auth: DappKey,
|
|
289
|
-
|
|
290
|
-
meta: &PermitMetadata,
|
|
290
|
+
permit: &ScenePermit<PermType>,
|
|
291
291
|
from: &mut UserStorage,
|
|
292
292
|
target: &mut UserStorage,
|
|
293
293
|
key: vector<vector<u8>>,
|
|
@@ -298,6 +298,10 @@ public fun set_record_reactive<DappKey: copy + drop>(
|
|
|
298
298
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
299
299
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(from) == dapp_key_str);
|
|
300
300
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(target) == dapp_key_str);
|
|
301
|
+
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
302
|
+
|
|
303
|
+
let scene_id = dapp_service::scene_permit_id(permit);
|
|
304
|
+
let meta = dapp_service::scene_permit_meta(permit);
|
|
301
305
|
|
|
302
306
|
// 1. Sender must be the initiator's canonical owner.
|
|
303
307
|
error::not_canonical_owner(ctx.sender() == dapp_service::canonical_owner(from));
|
|
@@ -319,11 +323,10 @@ public fun set_record_reactive<DappKey: copy + drop>(
|
|
|
319
323
|
dapp_service::set_user_record<DappKey>(target, key, field_names, values, false);
|
|
320
324
|
}
|
|
321
325
|
|
|
322
|
-
/// Update a single named field in another user's UserStorage, authorized by
|
|
323
|
-
public fun set_field_reactive<DappKey: copy + drop>(
|
|
326
|
+
/// Update a single named field in another user's UserStorage, authorized by a ScenePermit.
|
|
327
|
+
public fun set_field_reactive<DappKey: copy + drop, PermType>(
|
|
324
328
|
_auth: DappKey,
|
|
325
|
-
|
|
326
|
-
meta: &PermitMetadata,
|
|
329
|
+
permit: &ScenePermit<PermType>,
|
|
327
330
|
from: &mut UserStorage,
|
|
328
331
|
target: &mut UserStorage,
|
|
329
332
|
key: vector<vector<u8>>,
|
|
@@ -334,6 +337,10 @@ public fun set_field_reactive<DappKey: copy + drop>(
|
|
|
334
337
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
335
338
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(from) == dapp_key_str);
|
|
336
339
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(target) == dapp_key_str);
|
|
340
|
+
error::dapp_key_mismatch(dapp_service::scene_permit_dapp_key(permit) == dapp_key_str);
|
|
341
|
+
|
|
342
|
+
let scene_id = dapp_service::scene_permit_id(permit);
|
|
343
|
+
let meta = dapp_service::scene_permit_meta(permit);
|
|
337
344
|
|
|
338
345
|
error::not_canonical_owner(ctx.sender() == dapp_service::canonical_owner(from));
|
|
339
346
|
error::not_scene_participant(dapp_service::is_scene_participant(scene_id, dapp_service::canonical_owner(from)));
|
|
@@ -347,98 +354,14 @@ public fun set_field_reactive<DappKey: copy + drop>(
|
|
|
347
354
|
dapp_service::add_write_bytes(from, (field_value.length() as u256));
|
|
348
355
|
}
|
|
349
356
|
|
|
350
|
-
// ─── PermitMetadata primitives (public wrappers) ───────────────────────────────
|
|
351
|
-
|
|
352
|
-
/// Create a new PermitMetadata (no participants yet) and bulk-add initial
|
|
353
|
-
/// participants as dynamic fields. This is the standard entry point called
|
|
354
|
-
/// by codegen-generated create_<scene> functions.
|
|
355
|
-
///
|
|
356
|
-
/// The caller must pass `&mut id` — the scene object's UID — before wrapping
|
|
357
|
-
/// it in the scene struct. Initial participants are seeded via O(1) dynamic
|
|
358
|
-
/// field writes; subsequent joins also use the same path.
|
|
359
|
-
public fun init_scene_meta(
|
|
360
|
-
id: &mut UID,
|
|
361
|
-
participants: vector<address>,
|
|
362
|
-
expires_at: Option<u64>,
|
|
363
|
-
max_participants: Option<u64>,
|
|
364
|
-
): PermitMetadata {
|
|
365
|
-
let mut meta = dapp_service::new_scene_meta(expires_at, max_participants);
|
|
366
|
-
let mut i = 0;
|
|
367
|
-
let n = participants.length();
|
|
368
|
-
while (i < n) {
|
|
369
|
-
dapp_service::add_scene_participant(id, &mut meta, *participants.borrow(i));
|
|
370
|
-
i = i + 1;
|
|
371
|
-
};
|
|
372
|
-
meta
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/// Create a PermitMetadata in invitation mode: participants list starts empty,
|
|
376
|
-
/// invitees must call accept_scene_invitation to confirm before they can react.
|
|
377
|
-
public fun new_scene_meta_with_invitations(
|
|
378
|
-
invitees: vector<address>,
|
|
379
|
-
invites_expire_at: Option<u64>,
|
|
380
|
-
scene_expires_at: Option<u64>,
|
|
381
|
-
max_participants: Option<u64>,
|
|
382
|
-
): PermitMetadata {
|
|
383
|
-
dapp_service::new_scene_meta_with_invitations(invitees, invites_expire_at, scene_expires_at, max_participants)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/// Called by an invitee to confirm their participation in a scene.
|
|
387
|
-
///
|
|
388
|
-
/// Validates:
|
|
389
|
-
/// 1. The scene itself has not expired.
|
|
390
|
-
/// 2. The invitation window is still open (if invites_expire_at is set).
|
|
391
|
-
/// 3. ctx.sender() is in the invitees list.
|
|
392
|
-
/// On success: sender is moved from invitees into confirmed participants (DF).
|
|
393
|
-
///
|
|
394
|
-
/// Works for ALL Sui wallet types (Ed25519, Secp256k1, Secp256r1, zkLogin, multisig)
|
|
395
|
-
/// because authorization relies on Sui's native transaction sender verification.
|
|
396
|
-
public fun accept_scene_invitation<DappKey: copy + drop>(
|
|
397
|
-
_auth: DappKey,
|
|
398
|
-
id: &mut UID,
|
|
399
|
-
meta: &mut PermitMetadata,
|
|
400
|
-
ctx: &TxContext,
|
|
401
|
-
) {
|
|
402
|
-
// Scene must still be active.
|
|
403
|
-
error::scene_expired(dapp_service::is_scene_active(meta, ctx.epoch_timestamp_ms()));
|
|
404
|
-
let expire_opt = dapp_service::scene_invites_expire_at(meta);
|
|
405
|
-
if (option::is_some(&expire_opt)) {
|
|
406
|
-
error::invitation_expired(ctx.epoch_timestamp_ms() <= *option::borrow(&expire_opt));
|
|
407
|
-
};
|
|
408
|
-
let sender = ctx.sender();
|
|
409
|
-
error::not_participant(dapp_service::is_scene_invitee(meta, sender));
|
|
410
|
-
dapp_service::accept_scene_invitation_meta(id, meta, sender);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/// Add a participant to a scene (O(1) dynamic field write).
|
|
414
|
-
public fun add_scene_participant(id: &mut UID, meta: &mut PermitMetadata, addr: address) {
|
|
415
|
-
dapp_service::add_scene_participant(id, meta, addr)
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/// Remove a participant from a scene (O(1) dynamic field remove).
|
|
419
|
-
public fun remove_scene_participant(id: &mut UID, meta: &mut PermitMetadata, addr: address) {
|
|
420
|
-
dapp_service::remove_scene_participant(id, meta, addr)
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/// Returns true if the scene is still active (not expired).
|
|
424
|
-
public fun is_scene_active(meta: &PermitMetadata, now_ms: u64): bool {
|
|
425
|
-
dapp_service::is_scene_active(meta, now_ms)
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/// Returns true if addr is a registered participant in this scene (O(1) DF lookup).
|
|
429
|
-
public fun is_scene_participant(scene_id: &UID, addr: address): bool {
|
|
430
|
-
dapp_service::is_scene_participant(scene_id, addr)
|
|
431
|
-
}
|
|
432
|
-
|
|
433
357
|
// ─── Typed Object management primitives ──────────────────────────────────────
|
|
434
358
|
//
|
|
435
|
-
//
|
|
359
|
+
// Production path: create_and_share_typed_object / destroy_typed_object (used by codegen).
|
|
436
360
|
// entity_id uniqueness is scoped per (DApp, type_tag) — a guild and a boss
|
|
437
361
|
// can share the same entity_id bytes without collision.
|
|
438
362
|
|
|
439
|
-
///
|
|
440
|
-
|
|
441
|
-
/// Returns the new object's UID for the caller to embed in its struct.
|
|
363
|
+
/// Low-level UID primitive — test-only. Production code uses create_and_share_typed_object.
|
|
364
|
+
#[test_only]
|
|
442
365
|
public fun create_object<DappKey: copy + drop>(
|
|
443
366
|
_auth: DappKey,
|
|
444
367
|
dapp_storage: &mut DappStorage,
|
|
@@ -455,36 +378,8 @@ public fun create_object<DappKey: copy + drop>(
|
|
|
455
378
|
uid
|
|
456
379
|
}
|
|
457
380
|
|
|
458
|
-
/// Register an entity_id for a typed object that was created with a locally-owned UID.
|
|
459
|
-
/// Use this in codegen-generated create_<key> functions where the UID must remain in
|
|
460
|
-
/// the local scope (Sui verifier requires UID to be directly from sui::object::new).
|
|
461
|
-
public fun register_object_entity<DappKey: copy + drop>(
|
|
462
|
-
_auth: DappKey,
|
|
463
|
-
dapp_storage: &mut DappStorage,
|
|
464
|
-
type_tag: vector<u8>,
|
|
465
|
-
entity_id: vector<u8>,
|
|
466
|
-
object_id: address,
|
|
467
|
-
) {
|
|
468
|
-
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
469
|
-
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
470
|
-
dapp_service::register_object_entity_id(dapp_storage, type_tag, entity_id, object_id);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
/// Unregister an entity_id for a typed object. Use in codegen-generated destroy_<key>.
|
|
474
|
-
/// The caller must separately delete the UID with `sui::object::delete`.
|
|
475
|
-
public fun unregister_object_entity<DappKey: copy + drop>(
|
|
476
|
-
_auth: DappKey,
|
|
477
|
-
dapp_storage: &mut DappStorage,
|
|
478
|
-
type_tag: vector<u8>,
|
|
479
|
-
entity_id: vector<u8>,
|
|
480
|
-
) {
|
|
481
|
-
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
482
|
-
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
483
|
-
dapp_service::unregister_object_entity_id(dapp_storage, type_tag, entity_id);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
381
|
/// Unregister a typed object's entity_id from DappStorage and delete its UID.
|
|
487
|
-
|
|
382
|
+
#[test_only]
|
|
488
383
|
public fun destroy_object<DappKey: copy + drop>(
|
|
489
384
|
_auth: DappKey,
|
|
490
385
|
dapp_storage: &mut DappStorage,
|
|
@@ -499,16 +394,6 @@ public fun destroy_object<DappKey: copy + drop>(
|
|
|
499
394
|
sui::object::delete(uid);
|
|
500
395
|
}
|
|
501
396
|
|
|
502
|
-
/// Returns true if (type_tag, entity_id) is already registered for this DApp.
|
|
503
|
-
public fun has_object_entity_id<DappKey: copy + drop>(
|
|
504
|
-
_auth: DappKey,
|
|
505
|
-
dapp_storage: &DappStorage,
|
|
506
|
-
type_tag: vector<u8>,
|
|
507
|
-
entity_id: vector<u8>,
|
|
508
|
-
): bool {
|
|
509
|
-
dapp_service::has_object_entity_id(dapp_storage, type_tag, entity_id)
|
|
510
|
-
}
|
|
511
|
-
|
|
512
397
|
// ─── Framework-controlled ObjectStorage CRUD ─────────────────────────────────
|
|
513
398
|
//
|
|
514
399
|
// These functions replace the old DApp-side Bag manipulation pattern.
|
|
@@ -667,6 +552,7 @@ public fun destroy_typed_object<DappKey: copy + drop, ObjType>(
|
|
|
667
552
|
) {
|
|
668
553
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
669
554
|
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
555
|
+
error::dapp_paused(!dapp_service::dapp_paused(dapp_storage));
|
|
670
556
|
|
|
671
557
|
let type_tag = *dapp_service::object_storage_type(&storage); // &vector<u8> → copy
|
|
672
558
|
let entity_id = *dapp_service::object_storage_entity_id(&storage); // same
|
|
@@ -1388,6 +1274,7 @@ public fun buy_record<DappKey: copy + drop, CoinType>(
|
|
|
1388
1274
|
error::dapp_key_mismatch(dapp_service::listing_dapp_key(&listing) == dapp_key_str);
|
|
1389
1275
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(buyer_storage) == dapp_key_str);
|
|
1390
1276
|
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
1277
|
+
error::dapp_paused(!dapp_service::dapp_paused(dapp_storage));
|
|
1391
1278
|
|
|
1392
1279
|
// Buyer must own buyer_storage.
|
|
1393
1280
|
error::no_permission(ctx.sender() == dapp_service::canonical_owner(buyer_storage));
|
|
@@ -1466,6 +1353,7 @@ public fun buy_fungible_record<DappKey: copy + drop, CoinType>(
|
|
|
1466
1353
|
error::dapp_key_mismatch(dapp_service::listing_dapp_key(&listing) == dapp_key_str);
|
|
1467
1354
|
error::dapp_key_mismatch(dapp_service::user_storage_dapp_key(buyer_storage) == dapp_key_str);
|
|
1468
1355
|
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
1356
|
+
error::dapp_paused(!dapp_service::dapp_paused(dapp_storage));
|
|
1469
1357
|
|
|
1470
1358
|
error::no_permission(ctx.sender() == dapp_service::canonical_owner(buyer_storage));
|
|
1471
1359
|
// Buyer must not be the seller (prevents self-trade exploits).
|
|
@@ -2195,6 +2083,7 @@ public fun update_marketplace_fee(
|
|
|
2195
2083
|
/// Used by generated DApp buy functions to compute the fee to charge buyers.
|
|
2196
2084
|
/// All DApps share the same global rate; there is no per-DApp override.
|
|
2197
2085
|
public fun marketplace_fee_bps(dh: &DappHub): u64 {
|
|
2086
|
+
assert_framework_version(dh);
|
|
2198
2087
|
dapp_service::marketplace_fee_bps(dapp_service::get_config(dh))
|
|
2199
2088
|
}
|
|
2200
2089
|
|
|
@@ -2232,6 +2121,7 @@ public fun settle_marketplace_fee<DappKey: copy + drop, CoinType>(
|
|
|
2232
2121
|
assert_framework_version(dh);
|
|
2233
2122
|
let dapp_key_str = type_info::get_type_name_string<DappKey>();
|
|
2234
2123
|
error::dapp_key_mismatch(dapp_service::dapp_storage_dapp_key(dapp_storage) == dapp_key_str);
|
|
2124
|
+
error::dapp_paused(!dapp_service::dapp_paused(dapp_storage));
|
|
2235
2125
|
|
|
2236
2126
|
let total_fee = coin::value(&fee_coin);
|
|
2237
2127
|
if (total_fee == 0) {
|
|
@@ -2535,6 +2425,7 @@ public fun update_framework_fee(
|
|
|
2535
2425
|
/// sync_dapp_fee), not from this function. Use sync_dapp_fee after a pending fee
|
|
2536
2426
|
/// change has been committed to propagate the new rates to each DApp.
|
|
2537
2427
|
public fun get_effective_fees_at(dh: &DappHub, now_ms: u64): (u256, u256) {
|
|
2428
|
+
assert_framework_version(dh);
|
|
2538
2429
|
let cfg = dapp_service::get_fee_config(dh);
|
|
2539
2430
|
let effective_at = dapp_service::fee_effective_at_ms(cfg);
|
|
2540
2431
|
let pb = dapp_service::pending_base_fee(cfg);
|
|
@@ -2553,6 +2444,7 @@ public fun get_effective_fees_at(dh: &DappHub, now_ms: u64): (u256, u256) {
|
|
|
2553
2444
|
|
|
2554
2445
|
/// Return the current base-fee and bytes-fee without accounting for pending increases.
|
|
2555
2446
|
public fun get_effective_fees(dh: &DappHub): (u256, u256) {
|
|
2447
|
+
assert_framework_version(dh);
|
|
2556
2448
|
let cfg = dapp_service::get_fee_config(dh);
|
|
2557
2449
|
(
|
|
2558
2450
|
dapp_service::base_fee_per_write(cfg),
|
|
@@ -2821,6 +2713,9 @@ public fun ensure_not_paused<DappKey: copy + drop>(
|
|
|
2821
2713
|
|
|
2822
2714
|
// ─── Utility ─────────────────────────────────────────────────────────────────
|
|
2823
2715
|
|
|
2716
|
+
/// Returns the canonical dapp key string for a given DappKey type.
|
|
2717
|
+
/// Convenience helper for DApp developers who need to reference their key string
|
|
2718
|
+
/// (e.g. for off-chain indexing or event filtering).
|
|
2824
2719
|
public fun dapp_key<DappKey: copy + drop>(): String {
|
|
2825
2720
|
type_name::with_defining_ids<DappKey>().into_string()
|
|
2826
2721
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/// Covers the write_count / settled_count model (lazy settlement):
|
|
4
4
|
/// write_count tracking: set_record increments, offchain/delete do not
|
|
5
5
|
/// set_field increments write_count
|
|
6
|
-
/// max_unsettled_writes guard (
|
|
6
|
+
/// max_unsettled_writes guard (test harness write_limit=1_000; production default is 2_000)
|
|
7
7
|
/// settle_writes full settlement (all unsettled writes charged)
|
|
8
8
|
/// settle_writes skip when credit_pool == 0
|
|
9
9
|
/// settle_writes partial settlement (limited by available credits)
|
|
@@ -184,7 +184,7 @@ fun test_set_record_aborts_at_max_unsettled_writes() {
|
|
|
184
184
|
let ctx = test_scenario::ctx(&mut scenario);
|
|
185
185
|
let mut us = new_us(ctx);
|
|
186
186
|
|
|
187
|
-
//
|
|
187
|
+
// write_limit = 1_000 in test harness (production default: 2_000); fill to the limit.
|
|
188
188
|
let max_writes = 1000u64;
|
|
189
189
|
let mut i = 0u64;
|
|
190
190
|
while (i < max_writes) {
|
|
@@ -213,7 +213,7 @@ fun test_write_allowed_after_settlement_clears_debt() {
|
|
|
213
213
|
|
|
214
214
|
let mut us = new_us(ctx);
|
|
215
215
|
|
|
216
|
-
// Fill up to
|
|
216
|
+
// Fill up to test harness write_limit = 1_000 (production default: 2_000).
|
|
217
217
|
let max_writes = 1000u64;
|
|
218
218
|
let mut i = 0u64;
|
|
219
219
|
while (i < max_writes) {
|