diff --git a/.gitignore b/.gitignore
index 4f9cbbe5..c7e231e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
dist
node_modules
-.DS_Store
\ No newline at end of file
+.DS_Store
+.idea
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4654f0bf..c3f62862 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,54 +1,64 @@
-lockfileVersion: '6.1'
+lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
-dependencies:
- kolorist:
- specifier: ^1.8.0
- version: 1.8.0
- prompts:
- specifier: ^2.4.2
- version: 2.4.2
- typescript:
- specifier: ^4.7.4
- version: 4.7.4
-
-devDependencies:
- '@types/node':
- specifier: ^20.5.0
- version: 20.5.0
+importers:
+
+ .:
+ dependencies:
+ kolorist:
+ specifier: ^1.8.0
+ version: 1.8.0
+ prompts:
+ specifier: ^2.4.2
+ version: 2.4.2
+ typescript:
+ specifier: ^4.7.4
+ version: 4.7.4
+ devDependencies:
+ '@types/node':
+ specifier: ^20.5.0
+ version: 20.5.0
packages:
- /@types/node@20.5.0:
+ '@types/node@20.5.0':
resolution: {integrity: sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==}
- dev: true
- /kleur@3.0.3:
+ kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
- dev: false
- /kolorist@1.8.0:
+ kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
- dev: false
- /prompts@2.4.2:
+ prompts@2.4.2:
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
engines: {node: '>= 6'}
- dependencies:
- kleur: 3.0.3
- sisteransi: 1.0.5
- dev: false
- /sisteransi@1.0.5:
+ sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
- dev: false
- /typescript@4.7.4:
+ typescript@4.7.4:
resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==}
engines: {node: '>=4.2.0'}
hasBin: true
- dev: false
+
+snapshots:
+
+ '@types/node@20.5.0': {}
+
+ kleur@3.0.3: {}
+
+ kolorist@1.8.0: {}
+
+ prompts@2.4.2:
+ dependencies:
+ kleur: 3.0.3
+ sisteransi: 1.0.5
+
+ sisteransi@1.0.5: {}
+
+ typescript@4.7.4: {}
diff --git a/templates/nft-template/.gitignore b/templates/nft-template/.gitignore
new file mode 100644
index 00000000..f030ad0c
--- /dev/null
+++ b/templates/nft-template/.gitignore
@@ -0,0 +1,28 @@
+# Aptos related files
+.aptos
+.env
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/templates/nft-template/README.md b/templates/nft-template/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/templates/nft-template/contract_address.txt b/templates/nft-template/contract_address.txt
new file mode 100644
index 00000000..6f15fa43
--- /dev/null
+++ b/templates/nft-template/contract_address.txt
@@ -0,0 +1 @@
+0xc9d6f25bb6d465476ebfed667fa465975aedabb9664a26c261637d0d7e2b443a
diff --git a/templates/nft-template/frontend/.eslintrc.cjs b/templates/nft-template/frontend/.eslintrc.cjs
new file mode 100644
index 00000000..d6c95379
--- /dev/null
+++ b/templates/nft-template/frontend/.eslintrc.cjs
@@ -0,0 +1,18 @@
+module.exports = {
+ root: true,
+ env: { browser: true, es2020: true },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:react-hooks/recommended',
+ ],
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['react-refresh'],
+ rules: {
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+}
diff --git a/templates/nft-template/frontend/.gitignore b/templates/nft-template/frontend/.gitignore
new file mode 100644
index 00000000..a547bf36
--- /dev/null
+++ b/templates/nft-template/frontend/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/templates/nft-template/frontend/index.html b/templates/nft-template/frontend/index.html
new file mode 100644
index 00000000..8c09dfa1
--- /dev/null
+++ b/templates/nft-template/frontend/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Aptos dapp boilerplate
+
+
+
+
+
+
diff --git a/templates/nft-template/frontend/package.json b/templates/nft-template/frontend/package.json
new file mode 100644
index 00000000..64c47c59
--- /dev/null
+++ b/templates/nft-template/frontend/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "frontend",
+ "version": "0.0.0",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aptos-labs/wallet-adapter-ant-design": "^2.3.0",
+ "@aptos-labs/wallet-adapter-react": "^2.4.0",
+ "@pontem/wallet-adapter-plugin": "^0.2.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
+ "@typescript-eslint/parser": "^6.0.0",
+ "@vitejs/plugin-react": "^4.0.3",
+ "eslint": "^8.45.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.3",
+ "typescript": "^5.0.2",
+ "vite": "^4.4.5"
+ }
+}
diff --git a/templates/nft-template/frontend/public/aptos.png b/templates/nft-template/frontend/public/aptos.png
new file mode 100644
index 00000000..5aa7e657
Binary files /dev/null and b/templates/nft-template/frontend/public/aptos.png differ
diff --git a/templates/nft-template/frontend/src/App.tsx b/templates/nft-template/frontend/src/App.tsx
new file mode 100644
index 00000000..2dc50b05
--- /dev/null
+++ b/templates/nft-template/frontend/src/App.tsx
@@ -0,0 +1,21 @@
+import { WalletSelector } from "@aptos-labs/wallet-adapter-ant-design";
+import "@aptos-labs/wallet-adapter-ant-design/dist/index.css";
+import logo from "./assets/aptos.png";
+
+function App() {
+ return (
+ <>
+
+
Create Aptos Dapp
+
+
+
+
+
+
+
+ >
+ );
+}
+
+export default App;
diff --git a/templates/nft-template/frontend/src/abi.ts b/templates/nft-template/frontend/src/abi.ts
new file mode 100644
index 00000000..2593fa5d
--- /dev/null
+++ b/templates/nft-template/frontend/src/abi.ts
@@ -0,0 +1 @@
+export const ABI = {"address":"0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2","name":"todolist","friends":[],"exposed_functions":[{"name":"complete_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","u64"],"return":[]},{"name":"create_list","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer"],"return":[]},{"name":"create_task","visibility":"public","is_entry":true,"is_view":false,"generic_type_params":[],"params":["&signer","0x1::string::String"],"return":[]}],"structs":[{"name":"Task","is_native":false,"abilities":["copy","drop","store"],"generic_type_params":[],"fields":[{"name":"address","type":"address"},{"name":"content","type":"0x1::string::String"},{"name":"completed","type":"bool"}]},{"name":"TodoList","is_native":false,"abilities":["key"],"generic_type_params":[],"fields":[{"name":"tasks","type":"vector<0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2::todolist::Task>"},{"name":"set_task_event","type":"0x1::event::EventHandle<0x8f838ee41b0cc142e46dfeac5a68e50be1488594b91ca8eefd17682e8e86c3f2::todolist::Task>"}]}]} as const
diff --git a/templates/nft-template/frontend/src/assets/aptos.png b/templates/nft-template/frontend/src/assets/aptos.png
new file mode 100644
index 00000000..5aa7e657
Binary files /dev/null and b/templates/nft-template/frontend/src/assets/aptos.png differ
diff --git a/templates/nft-template/frontend/src/index.css b/templates/nft-template/frontend/src/index.css
new file mode 100644
index 00000000..bb0acd06
--- /dev/null
+++ b/templates/nft-template/frontend/src/index.css
@@ -0,0 +1,38 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+.navbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #333;
+ color: #fff;
+ padding: 10px 20px;
+}
+
+.navbar-text {
+ font-size: 20px;
+}
+
+.center-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh; /* Adjust this to control vertical centering */
+}
+
+.center-image {
+ max-width: 100%;
+ max-height: 100%;
+}
diff --git a/templates/nft-template/frontend/src/main.tsx b/templates/nft-template/frontend/src/main.tsx
new file mode 100644
index 00000000..aaa14862
--- /dev/null
+++ b/templates/nft-template/frontend/src/main.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+// wallet adapter
+import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
+// wallets
+import { PontemWallet } from "@pontem/wallet-adapter-plugin";
+
+import App from "./App";
+import "./index.css";
+
+const wallets = [new PontemWallet()];
+
+const root = ReactDOM.createRoot(
+ document.getElementById("root") as HTMLElement
+);
+root.render(
+
+ {
+ console.log("Custom error handling", error);
+ }}
+ >
+
+
+
+);
diff --git a/templates/nft-template/frontend/src/vite-env.d.ts b/templates/nft-template/frontend/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/templates/nft-template/frontend/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/templates/nft-template/frontend/tsconfig.json b/templates/nft-template/frontend/tsconfig.json
new file mode 100644
index 00000000..a7fc6fbf
--- /dev/null
+++ b/templates/nft-template/frontend/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/templates/nft-template/frontend/tsconfig.node.json b/templates/nft-template/frontend/tsconfig.node.json
new file mode 100644
index 00000000..42872c59
--- /dev/null
+++ b/templates/nft-template/frontend/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/templates/nft-template/frontend/vite.config.ts b/templates/nft-template/frontend/vite.config.ts
new file mode 100644
index 00000000..fa25f4fe
--- /dev/null
+++ b/templates/nft-template/frontend/vite.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ build: {
+ outDir: "build",
+ },
+ server: {
+ open: true,
+ },
+ plugins: [react()],
+});
diff --git a/templates/nft-template/move/.gitignore b/templates/nft-template/move/.gitignore
new file mode 100644
index 00000000..f930c403
--- /dev/null
+++ b/templates/nft-template/move/.gitignore
@@ -0,0 +1,2 @@
+build/
+.aptos
\ No newline at end of file
diff --git a/templates/nft-template/move/Move.toml b/templates/nft-template/move/Move.toml
new file mode 100644
index 00000000..7f7a0870
--- /dev/null
+++ b/templates/nft-template/move/Move.toml
@@ -0,0 +1,19 @@
+[package]
+name = "launchpad"
+version = "1.0.0"
+authors = []
+
+[addresses]
+launchpad_addr = "_"
+minter = "_"
+
+[dev-addresses]
+launchpad_addr = "0x100"
+minter = "0x101"
+
+[dependencies]
+AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "mainnet", subdir = "aptos-move/framework/aptos-framework"}
+AptosTokenObjects = { git = "https://github.com/aptos-labs/aptos-core.git", rev = "mainnet", subdir = "aptos-move/framework/aptos-token-objects"}
+TokenMinter = { git = "https://github.com/aptos-labs/token-minter.git", rev = "main", subdir = "token-minter"}
+
+[dev-dependencies]
diff --git a/templates/nft-template/move/sources/nft_launchpad.move b/templates/nft-template/move/sources/nft_launchpad.move
new file mode 100644
index 00000000..9adc05cb
--- /dev/null
+++ b/templates/nft-template/move/sources/nft_launchpad.move
@@ -0,0 +1,433 @@
+module launchpad_addr::nft_launchpad {
+ use std::option::{Self, Option};
+ use std::signer;
+ use std::string::{Self, String};
+ use std::vector;
+
+ use aptos_std::simple_map::{Self, SimpleMap};
+ use aptos_std::string_utils;
+
+ use aptos_framework::aptos_account;
+ use aptos_framework::event;
+ use aptos_framework::object::{Self, Object};
+
+ use aptos_token_objects::collection::{Self, Collection};
+ use aptos_token_objects::royalty::{Self, Royalty};
+ use aptos_token_objects::token::{Self, Token};
+
+ use minter::token_components;
+ use minter::mint_stage;
+ use minter::collection_components;
+
+ /// Sender is not admin
+ const ENOT_ADMIN: u64 = 1;
+ /// Sender is not pending admin
+ const ENOT_PENDING_ADMIN: u64 = 2;
+ /// Only admin can update mint fee collector
+ const EONLY_ADMIN_CAN_UPDATE_MINT_FEE_COLLECTOR: u64 = 3;
+ /// Only admin can create collection
+ const EONLY_ADMIN_CAN_CREATE_COLLECTION: u64 = 4;
+ /// No active mint stages
+ const E_NO_ACTIVE_STAGES: u64 = 5;
+
+ const ALLOWLIST_MINT_STAGE_CATEGORY: vector = b"Allowlist mint stage";
+ const PUBLIC_MINT_MINT_STAGE_CATEGORY: vector = b"Public mint mint stage";
+
+ #[event]
+ struct CreateCollectionEvent has store, drop {
+ creator_addr: address,
+ collection_owner_obj: Object,
+ collection_obj: Object,
+ max_supply: Option,
+ name: String,
+ uri: String,
+ pre_mint_amount: u64,
+ allowlist: Option>,
+ allowlist_start_time: Option,
+ allowlist_end_time: Option,
+ allowlist_mint_limit_per_addr: Option,
+ allowlist_mint_fee_per_nft: Option,
+ public_mint_start_time: Option,
+ public_mint_end_time: Option,
+ public_mint_limit_per_addr: Option,
+ public_mint_fee_per_nft: Option,
+ }
+
+ #[event]
+ struct MintNftEvent has store, drop {
+ collection_obj: Object,
+ nft_obj: Object,
+ recipient_addr: address,
+ mint_fee: u64,
+ }
+
+ /// Unique per collection
+ /// We need this object to own the collection object instead of contract directly owns the collection object
+ /// This helps us avoid address collision when we create multiple collections with same name
+ struct CollectionOwnerObjConfig has key {
+ /// Only thing it stores is the link to collection object
+ collection_obj: Object,
+ extend_ref: object::ExtendRef,
+ }
+
+ /// Unique per collection
+ struct CollectionConfig has key {
+ /// Key is stage, value is mint fee denomination
+ mint_fee_per_nft_by_stages: SimpleMap,
+ collection_owner_obj: Object,
+ }
+
+ /// Global per contract
+ struct Registry has key {
+ collection_objects: vector