create-sbc-app 0.1.1 → 0.1.2
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/README.md +127 -66
- package/bin/cli.js +19 -13
- package/package.json +33 -33
- package/src/cli.ts +0 -115
- package/src/copyTemplate.ts +0 -42
- package/src/index.js +0 -221
- package/src/types/prompts.d.ts +0 -3
- /package/templates/react/{.env → .env.template} +0 -0
- /package/templates/react/{.eslintrc.cjs → .eslintrc.cjs.template} +0 -0
- /package/templates/react/{README.md → README.md.template} +0 -0
- /package/templates/react/{eslint.config.js → eslint.config.js.template} +0 -0
- /package/templates/react/{index.html → index.html.template} +0 -0
- /package/templates/react/{package.json → package.json.template} +0 -0
- /package/templates/react/src/{App.css → App.css.template} +0 -0
- /package/templates/react/src/{App.tsx → App.tsx.template} +0 -0
- /package/templates/react/src/{env.d.ts → env.d.ts.template} +0 -0
- /package/templates/react/src/{index.css → index.css.template} +0 -0
- /package/templates/react/src/{main.tsx → main.tsx.template} +0 -0
- /package/templates/react/{tsconfig.json → tsconfig.json.template} +0 -0
- /package/templates/react/{tsconfig.node.json → tsconfig.node.json.template} +0 -0
- /package/templates/react/{vite.config.ts → vite.config.ts.template} +0 -0
package/README.md
CHANGED
|
@@ -1,105 +1,166 @@
|
|
|
1
1
|
# create-sbc-app
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The easiest way to get started with SBC Account Abstraction. Create feature-complete applications with gasless transactions in seconds.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
#
|
|
9
|
-
npx create-sbc-app my-
|
|
10
|
-
|
|
11
|
-
# Using yarn
|
|
12
|
-
yarn create sbc-app my-sbc-app
|
|
8
|
+
# Create a new SBC app
|
|
9
|
+
npx create-sbc-app my-app
|
|
13
10
|
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
```
|
|
11
|
+
# Or specify a template directly
|
|
12
|
+
npx create-sbc-app my-app --template react
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
# Navigate to your app
|
|
15
|
+
cd my-app
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- 🔒 **Account Abstraction**: Smart account creation and management
|
|
23
|
-
- 🎨 **Modern Stack**: TypeScript, ESLint, and modern tooling
|
|
24
|
-
- 🌙 **Dark Mode**: Built-in dark mode support
|
|
25
|
-
- 🔧 **Developer Experience**: Hot reloading, debugging tools, and more
|
|
17
|
+
# Install dependencies
|
|
18
|
+
pnpm install # or npm install
|
|
26
19
|
|
|
27
|
-
|
|
20
|
+
# Start development server
|
|
21
|
+
pnpm dev # or npm run dev
|
|
22
|
+
```
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
## CLI Options
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
- Minimal configuration
|
|
26
|
+
```bash
|
|
27
|
+
Usage: create-sbc-app [project-directory] [options]
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
Create a new SBC App Kit project with an opinionated template
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
Arguments:
|
|
32
|
+
project-directory Directory to create the new app in
|
|
39
33
|
|
|
40
34
|
Options:
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
--
|
|
44
|
-
|
|
35
|
+
-V, --version output the version number
|
|
36
|
+
-t, --template <type> Template to use: react, nextjs, or backend
|
|
37
|
+
--api-key <apiKey> Your SBC API key for immediate configuration
|
|
38
|
+
--wallet <wallet> Wallet integration (not yet implemented)
|
|
39
|
+
-h, --help display help for command
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
$ create-sbc-app my-app
|
|
43
|
+
$ create-sbc-app my-app --template react
|
|
44
|
+
$ create-sbc-app my-app --template react --api-key your-api-key
|
|
45
|
+
|
|
46
|
+
Available Templates:
|
|
47
|
+
- react React + Vite template with SBC integration
|
|
48
|
+
- nextjs Next.js template with SBC integration (coming soon)
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
##
|
|
51
|
+
## ✨ Features
|
|
52
|
+
|
|
53
|
+
The React template includes comprehensive, production-ready examples:
|
|
54
|
+
|
|
55
|
+
### 🔋 Core Functionality
|
|
48
56
|
|
|
49
|
-
|
|
57
|
+
- **Smart Account Management** - Automatic account creation and management
|
|
58
|
+
- **Gasless Transactions** - Send ETH and interact with contracts without gas fees
|
|
59
|
+
- **Gas Estimation** - Preview transaction costs before sending
|
|
60
|
+
- **Batch Transactions** - Send multiple operations in a single transaction
|
|
61
|
+
- **Real-time Balance Tracking** - Monitor account balances and transaction status
|
|
62
|
+
- **Error Handling** - Comprehensive error messages and recovery suggestions
|
|
63
|
+
|
|
64
|
+
### 🎨 User Experience
|
|
65
|
+
|
|
66
|
+
- **Modern UI Design** - Beautiful, responsive interfaces
|
|
67
|
+
- **Form Validation** - Real-time address and input validation
|
|
68
|
+
- **Loading States** - Clear feedback during operations
|
|
69
|
+
- **Success/Error Feedback** - Visual confirmation of transaction status
|
|
70
|
+
- **Block Explorer Integration** - Direct links to view transactions
|
|
71
|
+
- **Copy-to-Clipboard** - Easy address and hash copying
|
|
72
|
+
|
|
73
|
+
### 🛠️ Developer Experience
|
|
74
|
+
|
|
75
|
+
- **TypeScript Support** - Full type safety
|
|
76
|
+
- **Environment Configuration** - Secure API key and settings management
|
|
77
|
+
- **Debug Logging** - Comprehensive development logging
|
|
78
|
+
- **Hot Reload** - Fast development iteration
|
|
79
|
+
- **Production Ready** - Optimized builds and deployment preparation
|
|
80
|
+
|
|
81
|
+
## 🚀 React Template
|
|
82
|
+
|
|
83
|
+
**Best for:** Client-side applications, rapid prototyping, and production use
|
|
50
84
|
|
|
51
85
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
cd create-sbc-app
|
|
86
|
+
npx create-sbc-app my-app
|
|
87
|
+
```
|
|
55
88
|
|
|
56
|
-
|
|
57
|
-
npm install
|
|
89
|
+
**Features:**
|
|
58
90
|
|
|
59
|
-
|
|
60
|
-
|
|
91
|
+
- Fast development setup
|
|
92
|
+
- Hot module replacement
|
|
93
|
+
- Built-in testing framework
|
|
94
|
+
- Easy deployment to static hosts
|
|
95
|
+
- Modern React patterns and hooks
|
|
96
|
+
|
|
97
|
+
## 📝 Configuration
|
|
98
|
+
|
|
99
|
+
### Environment Variables
|
|
100
|
+
|
|
101
|
+
The template includes comprehensive environment configuration:
|
|
102
|
+
|
|
103
|
+
#### Required
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Your SBC API key (get from SBC dashboard)
|
|
107
|
+
VITE_SBC_API_KEY=your_api_key_here
|
|
61
108
|
```
|
|
62
109
|
|
|
63
|
-
|
|
110
|
+
## 📱 UI Components
|
|
111
|
+
|
|
112
|
+
The template includes:
|
|
113
|
+
|
|
114
|
+
- Account information display with copy functionality
|
|
115
|
+
- Transaction forms with validation
|
|
116
|
+
- Gas estimation interfaces
|
|
117
|
+
- Success/error feedback with block explorer links
|
|
118
|
+
- Responsive design with dark mode support
|
|
119
|
+
|
|
120
|
+
## 🚀 Development Workflow
|
|
64
121
|
|
|
65
|
-
1. Create
|
|
122
|
+
### 1. Create Your App
|
|
66
123
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
124
|
+
```bash
|
|
125
|
+
npx create-sbc-app my-sbc-app
|
|
126
|
+
cd my-sbc-app
|
|
127
|
+
```
|
|
70
128
|
|
|
71
|
-
2.
|
|
72
|
-
- Choose the type of change (major, minor, patch)
|
|
73
|
-
- Write a description of the changes
|
|
74
|
-
- Select which packages are affected
|
|
129
|
+
### 2. Set Up Environment
|
|
75
130
|
|
|
76
|
-
|
|
131
|
+
```bash
|
|
132
|
+
# Copy environment template
|
|
133
|
+
cp .env.template .env
|
|
77
134
|
|
|
78
|
-
|
|
135
|
+
# Add your API key
|
|
136
|
+
echo "VITE_SBC_API_KEY=your_actual_api_key" >> .env
|
|
137
|
+
```
|
|
79
138
|
|
|
80
|
-
|
|
139
|
+
### 3. Start Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npm install
|
|
143
|
+
npm run dev
|
|
144
|
+
```
|
|
81
145
|
|
|
82
|
-
|
|
83
|
-
npm run version
|
|
84
|
-
```
|
|
146
|
+
### 4. Test Features
|
|
85
147
|
|
|
86
|
-
|
|
148
|
+
- Connect and view your smart account
|
|
149
|
+
- Try sending test transactions
|
|
150
|
+
- Experiment with gas estimation
|
|
151
|
+
- Test batch transactions
|
|
87
152
|
|
|
88
|
-
|
|
153
|
+
### 5. Customize and Build
|
|
89
154
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
155
|
+
- Modify the UI to match your needs
|
|
156
|
+
- Add your own smart contract interactions
|
|
157
|
+
- Build for production
|
|
93
158
|
|
|
94
|
-
##
|
|
159
|
+
## 📚 Documentation
|
|
95
160
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
3. Create a changeset (`npm run changeset`)
|
|
99
|
-
4. Commit your changes (`git commit -am 'Add some amazing feature'`)
|
|
100
|
-
5. Push to the branch (`git push origin feature/amazing-feature`)
|
|
101
|
-
6. Open a Pull Request
|
|
161
|
+
- **[SBC API Documentation](https://docs.stablecoin.xyz)** - Complete API reference
|
|
162
|
+
- **[GitHub Repository](https://github.com/stablecoinxyz/app-kit)** - Source code and examples
|
|
102
163
|
|
|
103
|
-
## License
|
|
164
|
+
## 📄 License
|
|
104
165
|
|
|
105
|
-
MIT
|
|
166
|
+
MIT - Built with ❤️ by the SBC team
|
package/bin/cli.js
CHANGED
|
@@ -9,10 +9,22 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
9
9
|
const program = new Command();
|
|
10
10
|
program
|
|
11
11
|
.name('create-sbc-app')
|
|
12
|
+
.description('Create a new SBC App Kit project with an opinionated template')
|
|
13
|
+
.version('0.1.0')
|
|
12
14
|
.argument('[project-directory]', 'Directory to create the new app in')
|
|
13
|
-
.option('-t, --template <template>', 'Template to use
|
|
14
|
-
.option('--api-key <apiKey>', 'Your SBC API key')
|
|
15
|
+
.option('-t, --template <template>', 'Template to use: react, nextjs, or backend')
|
|
16
|
+
.option('--api-key <apiKey>', 'Your SBC API key for immediate configuration')
|
|
15
17
|
.option('--wallet <wallet>', 'Wallet integration (not yet implemented)')
|
|
18
|
+
.addHelpText('after', `
|
|
19
|
+
Examples:
|
|
20
|
+
$ create-sbc-app my-app
|
|
21
|
+
$ create-sbc-app my-app --template react
|
|
22
|
+
$ create-sbc-app my-app --template react --api-key your-api-key
|
|
23
|
+
|
|
24
|
+
Available Templates:
|
|
25
|
+
- react React + Vite template with SBC integration
|
|
26
|
+
- nextjs Next.js template with SBC integration (coming soon)
|
|
27
|
+
`)
|
|
16
28
|
.action(async (dir, options) => {
|
|
17
29
|
if (options.wallet) {
|
|
18
30
|
console.log('Wallet integration not yet implemented.');
|
|
@@ -20,8 +32,7 @@ program
|
|
|
20
32
|
}
|
|
21
33
|
const templateChoices = [
|
|
22
34
|
{ title: 'React', value: 'react' },
|
|
23
|
-
{ title: 'Next.js', value: 'nextjs' }
|
|
24
|
-
{ title: 'Backend', value: 'backend' }
|
|
35
|
+
{ title: 'Next.js', value: 'nextjs' }
|
|
25
36
|
];
|
|
26
37
|
// Use provided argument or prompt for project directory
|
|
27
38
|
let projectDir = dir && dir.trim() ? dir.trim() : '';
|
|
@@ -38,7 +49,7 @@ program
|
|
|
38
49
|
projectDir = res.dir.trim();
|
|
39
50
|
}
|
|
40
51
|
// Use provided option or prompt for template
|
|
41
|
-
let template = options.template && ['react', 'nextjs'
|
|
52
|
+
let template = options.template && ['react', 'nextjs'].includes(options.template) ? options.template : '';
|
|
42
53
|
if (!template) {
|
|
43
54
|
const res = await prompts({
|
|
44
55
|
type: 'select',
|
|
@@ -50,8 +61,8 @@ program
|
|
|
50
61
|
console.log('Template selection is required.');
|
|
51
62
|
process.exit(1);
|
|
52
63
|
}
|
|
53
|
-
template =
|
|
54
|
-
if (!template) {
|
|
64
|
+
template = res.template; // The value is already what we want from the choices
|
|
65
|
+
if (!template || !['react', 'nextjs'].includes(template)) {
|
|
55
66
|
console.log('Template selection is required.');
|
|
56
67
|
process.exit(1);
|
|
57
68
|
}
|
|
@@ -93,12 +104,7 @@ program
|
|
|
93
104
|
console.log(` # Edit .env and add your SBC API key`);
|
|
94
105
|
}
|
|
95
106
|
console.log(` pnpm install # or npm install`);
|
|
96
|
-
|
|
97
|
-
console.log(' pnpm start # or npm run start');
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
console.log(' pnpm dev # or npm run dev');
|
|
101
|
-
}
|
|
107
|
+
console.log(' pnpm dev # or npm run dev');
|
|
102
108
|
console.log('\nHappy hacking!');
|
|
103
109
|
});
|
|
104
110
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-sbc-app",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "commonjs",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Scaffold a new SBC App Kit project with one command.",
|
|
6
5
|
"bin": {
|
|
7
|
-
"create-sbc-app": "
|
|
6
|
+
"create-sbc-app": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch",
|
|
11
|
+
"start": "node bin/cli.js",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"commander": "^11.0.0",
|
|
17
|
+
"fs-extra": "^11.1.1",
|
|
18
|
+
"prompts": "^2.4.2"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/fs-extra": "^11.0.4",
|
|
22
|
+
"typescript": "^5.8.3"
|
|
8
23
|
},
|
|
9
24
|
"files": [
|
|
10
|
-
"bin",
|
|
11
|
-
"
|
|
12
|
-
"templates",
|
|
25
|
+
"bin/",
|
|
26
|
+
"templates/",
|
|
13
27
|
"README.md"
|
|
14
28
|
],
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/stablecoinxyz/create-sbc-app.git"
|
|
21
35
|
},
|
|
22
36
|
"keywords": [
|
|
23
37
|
"sbc",
|
|
24
38
|
"account-abstraction",
|
|
25
39
|
"ethereum",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
40
|
+
"create-app",
|
|
41
|
+
"template",
|
|
42
|
+
"react",
|
|
43
|
+
"nextjs",
|
|
44
|
+
"vite"
|
|
28
45
|
],
|
|
29
|
-
"author": "
|
|
46
|
+
"author": "SBC Team",
|
|
30
47
|
"license": "MIT",
|
|
31
|
-
"repository": {
|
|
32
|
-
"type": "git",
|
|
33
|
-
"url": "https://github.com/stablecoinxyz/create-sbc-app.git"
|
|
34
|
-
},
|
|
35
48
|
"bugs": {
|
|
36
49
|
"url": "https://github.com/stablecoinxyz/create-sbc-app/issues"
|
|
37
50
|
},
|
|
38
51
|
"homepage": "https://github.com/stablecoinxyz/create-sbc-app#readme",
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": ">=18.0.0"
|
|
41
|
-
},
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"chalk": "^4.1.2",
|
|
44
|
-
"commander": "^12.0.0",
|
|
45
|
-
"fs-extra": "^11.2.0",
|
|
46
|
-
"inquirer": "^8.2.6",
|
|
47
|
-
"ora": "^5.4.1"
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@changesets/cli": "^2.27.1"
|
|
51
|
-
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
|
54
54
|
}
|
package/src/cli.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { Command } from 'commander';
|
|
3
|
-
import prompts from 'prompts';
|
|
4
|
-
import { copyTemplate } from './copyTemplate.js';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import fs from 'fs-extra';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
|
|
9
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
|
|
11
|
-
const program = new Command();
|
|
12
|
-
|
|
13
|
-
program
|
|
14
|
-
.name('create-sbc-app')
|
|
15
|
-
.argument('[project-directory]', 'Directory to create the new app in')
|
|
16
|
-
.option('-t, --template <template>', 'Template to use (react, nextjs, backend)')
|
|
17
|
-
.option('--api-key <apiKey>', 'Your SBC API key')
|
|
18
|
-
.option('--wallet <wallet>', 'Wallet integration (not yet implemented)')
|
|
19
|
-
.action(async (dir, options) => {
|
|
20
|
-
if (options.wallet) {
|
|
21
|
-
console.log('Wallet integration not yet implemented.');
|
|
22
|
-
process.exit(0);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const templateChoices = [
|
|
26
|
-
{ title: 'React', value: 'react' },
|
|
27
|
-
{ title: 'Next.js', value: 'nextjs' },
|
|
28
|
-
{ title: 'Backend', value: 'backend' }
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
// Use provided argument or prompt for project directory
|
|
32
|
-
let projectDir = dir && dir.trim() ? dir.trim() : '';
|
|
33
|
-
if (!projectDir) {
|
|
34
|
-
const res = await prompts({
|
|
35
|
-
type: 'text',
|
|
36
|
-
name: 'dir',
|
|
37
|
-
message: 'Project directory:'
|
|
38
|
-
});
|
|
39
|
-
if (!res.dir || !res.dir.trim()) {
|
|
40
|
-
console.log('Project directory is required.');
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
projectDir = res.dir.trim();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Use provided option or prompt for template
|
|
47
|
-
let template = options.template && ['react', 'nextjs', 'backend'].includes(options.template) ? options.template : '';
|
|
48
|
-
if (!template) {
|
|
49
|
-
const res = await prompts({
|
|
50
|
-
type: 'select',
|
|
51
|
-
name: 'template',
|
|
52
|
-
message: 'Which template?',
|
|
53
|
-
choices: templateChoices
|
|
54
|
-
});
|
|
55
|
-
if (res.template === undefined) {
|
|
56
|
-
console.log('Template selection is required.');
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
template = templateChoices[res.template]?.value;
|
|
60
|
-
if (!template) {
|
|
61
|
-
console.log('Template selection is required.');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Use provided option or prompt for API key
|
|
67
|
-
let apiKey = options.apiKey && options.apiKey.trim() ? options.apiKey.trim() : '';
|
|
68
|
-
if (!apiKey) {
|
|
69
|
-
const res = await prompts({
|
|
70
|
-
type: 'text',
|
|
71
|
-
name: 'apiKey',
|
|
72
|
-
message: 'Your SBC API key (or leave empty to set later):'
|
|
73
|
-
});
|
|
74
|
-
apiKey = res.apiKey ? res.apiKey.trim() : 'your-sbc-api-key';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const targetDir = path.resolve(process.cwd(), projectDir);
|
|
78
|
-
const templateDir = path.resolve(__dirname, '../templates', template);
|
|
79
|
-
|
|
80
|
-
if (fs.existsSync(targetDir)) {
|
|
81
|
-
const res = await prompts({
|
|
82
|
-
type: 'confirm',
|
|
83
|
-
name: 'overwrite',
|
|
84
|
-
message: `Directory ${projectDir} already exists. Overwrite?`,
|
|
85
|
-
initial: false
|
|
86
|
-
});
|
|
87
|
-
if (!res.overwrite) {
|
|
88
|
-
console.log('Aborted.');
|
|
89
|
-
process.exit(0);
|
|
90
|
-
}
|
|
91
|
-
await fs.remove(targetDir);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
await copyTemplate(templateDir, targetDir, {
|
|
95
|
-
projectName: projectDir,
|
|
96
|
-
chain: 'baseSepolia',
|
|
97
|
-
apiKey: apiKey
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
console.log(`\nSuccess! Created ${projectDir} using the ${template} template.`);
|
|
101
|
-
console.log(`\nNext steps:`);
|
|
102
|
-
console.log(` cd ${projectDir}`);
|
|
103
|
-
if (!options.apiKey && apiKey === 'your-sbc-api-key') {
|
|
104
|
-
console.log(` # Edit .env and add your SBC API key`);
|
|
105
|
-
}
|
|
106
|
-
console.log(` pnpm install # or npm install`);
|
|
107
|
-
if (template === 'backend') {
|
|
108
|
-
console.log(' pnpm start # or npm run start');
|
|
109
|
-
} else {
|
|
110
|
-
console.log(' pnpm dev # or npm run dev');
|
|
111
|
-
}
|
|
112
|
-
console.log('\nHappy hacking!');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
program.parse();
|
package/src/copyTemplate.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
interface TemplateVars {
|
|
5
|
-
projectName: string;
|
|
6
|
-
chain: string;
|
|
7
|
-
apiKey: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function copyTemplate(src: string, dest: string, templateVars: TemplateVars = { projectName: 'my-sbc-app', chain: 'baseSepolia', apiKey: 'your-sbc-api-key' }) {
|
|
11
|
-
await fs.ensureDir(dest);
|
|
12
|
-
|
|
13
|
-
const items = await fs.readdir(src);
|
|
14
|
-
|
|
15
|
-
for (const item of items) {
|
|
16
|
-
const srcPath = path.join(src, item);
|
|
17
|
-
const stat = await fs.stat(srcPath);
|
|
18
|
-
|
|
19
|
-
if (stat.isDirectory()) {
|
|
20
|
-
// Recursively copy directories
|
|
21
|
-
const destPath = path.join(dest, item);
|
|
22
|
-
await copyTemplate(srcPath, destPath, templateVars);
|
|
23
|
-
} else {
|
|
24
|
-
let destName = item;
|
|
25
|
-
if (item.endsWith('.template')) {
|
|
26
|
-
destName = item.replace(/\.template$/, '');
|
|
27
|
-
const destPath = path.join(dest, destName);
|
|
28
|
-
// Only do text replacement for .template files
|
|
29
|
-
const content = await fs.readFile(srcPath, 'utf-8');
|
|
30
|
-
const processedContent = content
|
|
31
|
-
.replace(/\{\{projectName\}\}/g, templateVars.projectName)
|
|
32
|
-
.replace(/\{\{chain\}\}/g, templateVars.chain)
|
|
33
|
-
.replace(/\{\{apiKey\}\}/g, templateVars.apiKey);
|
|
34
|
-
await fs.writeFile(destPath, processedContent);
|
|
35
|
-
} else {
|
|
36
|
-
// Copy all other files (including images) as binary
|
|
37
|
-
const destPath = path.join(dest, destName);
|
|
38
|
-
await fs.copy(srcPath, destPath);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
package/src/index.js
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
const inquirer = require('inquirer');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
const ora = require('ora');
|
|
6
|
-
const { exec } = require('child_process');
|
|
7
|
-
const { promisify } = require('util');
|
|
8
|
-
|
|
9
|
-
const execAsync = promisify(exec);
|
|
10
|
-
|
|
11
|
-
// Chain configuration mapping
|
|
12
|
-
const CHAIN_CONFIG = {
|
|
13
|
-
baseSepolia: 'baseSepolia',
|
|
14
|
-
base: 'base'
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
async function createApp(projectName, options) {
|
|
18
|
-
console.log(chalk.cyan('🚀 Welcome to SBC App Creator!'));
|
|
19
|
-
console.log();
|
|
20
|
-
|
|
21
|
-
// Interactive prompts if not provided
|
|
22
|
-
const answers = await inquirer.prompt([
|
|
23
|
-
{
|
|
24
|
-
type: 'input',
|
|
25
|
-
name: 'projectName',
|
|
26
|
-
message: 'What is your project name?',
|
|
27
|
-
default: projectName || 'my-sbc-app',
|
|
28
|
-
when: !projectName,
|
|
29
|
-
validate: (input) => {
|
|
30
|
-
if (!input.trim()) return 'Project name is required';
|
|
31
|
-
if (!/^[a-z0-9-_]+$/i.test(input)) return 'Project name can only contain letters, numbers, hyphens, and underscores';
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
type: 'list',
|
|
37
|
-
name: 'template',
|
|
38
|
-
message: 'Which template would you like to use?',
|
|
39
|
-
choices: [
|
|
40
|
-
{ name: 'Next.js (Recommended)', value: 'nextjs' },
|
|
41
|
-
{ name: 'React', value: 'react' },
|
|
42
|
-
{ name: 'Vanilla JavaScript', value: 'vanilla' }
|
|
43
|
-
],
|
|
44
|
-
when: !options.template
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
type: 'input',
|
|
48
|
-
name: 'apiKey',
|
|
49
|
-
message: 'Enter your SBC API key (or leave empty to set later):',
|
|
50
|
-
when: !options.apiKey
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
type: 'list',
|
|
54
|
-
name: 'chain',
|
|
55
|
-
message: 'Which chain would you like to target?',
|
|
56
|
-
choices: [
|
|
57
|
-
{ name: 'Base Sepolia (Testnet)', value: 'baseSepolia' },
|
|
58
|
-
{ name: 'Base Mainnet', value: 'base' }
|
|
59
|
-
],
|
|
60
|
-
default: 'baseSepolia'
|
|
61
|
-
}
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
const config = {
|
|
65
|
-
projectName: projectName || answers.projectName,
|
|
66
|
-
template: options.template || answers.template,
|
|
67
|
-
apiKey: options.apiKey || answers.apiKey || 'sbc-your-api-key-here',
|
|
68
|
-
chain: answers.chain || 'baseSepolia',
|
|
69
|
-
skipInstall: options.skipInstall || false
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
await scaffoldProject(config);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function scaffoldProject(config) {
|
|
76
|
-
const { projectName, template, apiKey, chain, skipInstall } = config;
|
|
77
|
-
const targetDir = path.join(process.cwd(), projectName);
|
|
78
|
-
|
|
79
|
-
// Check if directory exists
|
|
80
|
-
if (await fs.pathExists(targetDir)) {
|
|
81
|
-
console.log(chalk.red(`❌ Directory ${projectName} already exists!`));
|
|
82
|
-
const overwrite = await inquirer.prompt([
|
|
83
|
-
{
|
|
84
|
-
type: 'confirm',
|
|
85
|
-
name: 'overwrite',
|
|
86
|
-
message: 'Do you want to overwrite it?',
|
|
87
|
-
default: false
|
|
88
|
-
}
|
|
89
|
-
]);
|
|
90
|
-
|
|
91
|
-
if (!overwrite.overwrite) {
|
|
92
|
-
console.log(chalk.yellow('Cancelled.'));
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
await fs.remove(targetDir);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const spinner = ora('Creating project structure...').start();
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
// Copy template files
|
|
103
|
-
const templateDir = path.join(__dirname, '..', 'templates', template);
|
|
104
|
-
await fs.copy(templateDir, targetDir);
|
|
105
|
-
|
|
106
|
-
spinner.text = 'Configuring project...';
|
|
107
|
-
|
|
108
|
-
// Replace template variables
|
|
109
|
-
await replaceTemplateVariables(targetDir, {
|
|
110
|
-
projectName,
|
|
111
|
-
apiKey,
|
|
112
|
-
chain: CHAIN_CONFIG[chain]
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
if (!skipInstall) {
|
|
116
|
-
spinner.text = 'Installing dependencies...';
|
|
117
|
-
|
|
118
|
-
// Install dependencies
|
|
119
|
-
await execAsync('npm install', { cwd: targetDir });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
spinner.succeed(chalk.green('Project created successfully!'));
|
|
123
|
-
|
|
124
|
-
// Success message
|
|
125
|
-
console.log();
|
|
126
|
-
console.log(chalk.green(`✅ ${projectName} is ready!`));
|
|
127
|
-
console.log();
|
|
128
|
-
|
|
129
|
-
if (apiKey === 'sbc-your-api-key-here') {
|
|
130
|
-
console.log(chalk.yellow('🔑 IMPORTANT: Setup your SBC API key first!'));
|
|
131
|
-
console.log();
|
|
132
|
-
console.log('1. Get your API key:');
|
|
133
|
-
console.log(chalk.cyan(' Visit: https://dashboard.stablecoin.xyz'));
|
|
134
|
-
console.log();
|
|
135
|
-
console.log('2. Configure environment variables:');
|
|
136
|
-
console.log(chalk.cyan(` cd ${projectName}`));
|
|
137
|
-
if (template === 'react') {
|
|
138
|
-
console.log(chalk.cyan(' # Edit the .env file and replace the API key:'));
|
|
139
|
-
console.log(chalk.cyan(' VITE_SBC_API_KEY=your_real_api_key_here'));
|
|
140
|
-
} else if (template === 'nextjs') {
|
|
141
|
-
console.log(chalk.cyan(' # Edit the .env.local file and replace the API key:'));
|
|
142
|
-
console.log(chalk.cyan(' SBC_API_KEY=your_real_api_key_here'));
|
|
143
|
-
} else {
|
|
144
|
-
console.log(chalk.cyan(' # Check your project files for API key configuration'));
|
|
145
|
-
}
|
|
146
|
-
console.log();
|
|
147
|
-
console.log('3. Start the development server:');
|
|
148
|
-
} else {
|
|
149
|
-
console.log('Next steps:');
|
|
150
|
-
console.log(chalk.cyan(` cd ${projectName}`));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (skipInstall) {
|
|
154
|
-
console.log(chalk.cyan(' npm install'));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.log(chalk.cyan(' npm run dev'));
|
|
158
|
-
console.log();
|
|
159
|
-
|
|
160
|
-
if (template === 'react') {
|
|
161
|
-
console.log('🚀 Your React app includes:');
|
|
162
|
-
console.log(' • Gasless transaction example');
|
|
163
|
-
console.log(' • Wallet connection component');
|
|
164
|
-
console.log(' • Balance checking functionality');
|
|
165
|
-
console.log(' • Complete error handling');
|
|
166
|
-
console.log(' • Modern Vite + TypeScript setup');
|
|
167
|
-
console.log();
|
|
168
|
-
console.log('💡 After connecting your wallet, try the "Send Gasless TX" button!');
|
|
169
|
-
} else if (template === 'nextjs') {
|
|
170
|
-
console.log('🚀 Your Next.js app is ready with SBC integration!');
|
|
171
|
-
} else {
|
|
172
|
-
console.log('🚀 Your vanilla app is ready with SBC integration!');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
console.log();
|
|
176
|
-
console.log('📚 Documentation: https://docs.stablecoin.xyz');
|
|
177
|
-
console.log('💬 Community: https://t.me/stablecoin_xyz');
|
|
178
|
-
|
|
179
|
-
} catch (error) {
|
|
180
|
-
spinner.fail('Failed to create project');
|
|
181
|
-
console.error(chalk.red('Error:', error.message));
|
|
182
|
-
|
|
183
|
-
// Cleanup on failure
|
|
184
|
-
if (await fs.pathExists(targetDir)) {
|
|
185
|
-
await fs.remove(targetDir);
|
|
186
|
-
}
|
|
187
|
-
process.exit(1);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async function replaceTemplateVariables(dir, variables) {
|
|
192
|
-
const walk = async (currentPath) => {
|
|
193
|
-
const items = await fs.readdir(currentPath);
|
|
194
|
-
|
|
195
|
-
for (const item of items) {
|
|
196
|
-
const fullPath = path.join(currentPath, item);
|
|
197
|
-
const stat = await fs.stat(fullPath);
|
|
198
|
-
|
|
199
|
-
if (stat.isDirectory()) {
|
|
200
|
-
await walk(fullPath);
|
|
201
|
-
} else if (item.endsWith('.template')) {
|
|
202
|
-
let content = await fs.readFile(fullPath, 'utf8');
|
|
203
|
-
|
|
204
|
-
// Replace variables
|
|
205
|
-
Object.entries(variables).forEach(([key, value]) => {
|
|
206
|
-
const regex = new RegExp(`{{${key}}}`, 'g');
|
|
207
|
-
content = content.replace(regex, value);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Remove .template extension
|
|
211
|
-
const newPath = fullPath.replace('.template', '');
|
|
212
|
-
await fs.writeFile(newPath, content);
|
|
213
|
-
await fs.remove(fullPath);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
await walk(dir);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
module.exports = createApp;
|
package/src/types/prompts.d.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|