@offckb/cli 0.1.0-rc5 → 0.1.0-rc7

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 CHANGED
@@ -23,6 +23,14 @@ Start building on Nervos blockchain, right now, right away!
23
23
  - [Install](#install)
24
24
  - [Usage](#usage)
25
25
  - [Get started](#get-started)
26
+ - [Step 1: Create A Project](#step-1-create-a-project)
27
+ - [Step 2: Start the Devnet](#step-2-start-the-devnet)
28
+ - [Step 3: Access Pre-funded Accounts](#step-3-access-pre-funded-accounts)
29
+ - [Dapp Templates](#dapp-templates)
30
+ - [View and transfer balance](#view-and-transfer-balance)
31
+ - [Write \& read on-chain messages](#write--read-on-chain-messages)
32
+ - [Issue custom token via xUDT scripts](#issue-custom-token-via-xudt-scripts)
33
+ - [Create on-chain digital object via Spore protocol](#create-on-chain-digital-object-via-spore-protocol)
26
34
  - [Built-in scripts](#built-in-scripts)
27
35
  - [Accounts](#accounts)
28
36
  - [About Lumos](#about-lumos)
@@ -48,6 +56,8 @@ offckb list-hashes # list built-in scripts hashes, equals `ckb list-hashes`
48
56
 
49
57
  ## Get started
50
58
 
59
+ ### Step 1: Create A Project
60
+
51
61
  ```sh
52
62
  offckb init my-awesome-ckb-dapp
53
63
 
@@ -70,7 +80,9 @@ Server running at http://localhost:1234
70
80
  ✨ Built in 10ms
71
81
  ```
72
82
 
73
- open another terminal and start the devnet:
83
+ ### Step 2: Start the Devnet
84
+
85
+ Open another terminal and run:
74
86
 
75
87
  ```sh
76
88
  offckb node
@@ -83,7 +95,11 @@ CKB-Miner: 2024-03-04 14:35:17.567 +00:00 client INFO ckb_miner::miner Found! #
83
95
  #...
84
96
  ```
85
97
 
86
- open another terminal and check the accounts to use:
98
+ You can leave this terminal open to keep the devnet running, feel free to `ctrl+c` to exit the terminal and stop the local blockchain.
99
+
100
+ ### Step 3: Access Pre-funded Accounts
101
+
102
+ Open another terminal and check the accounts to use:
87
103
 
88
104
  ```sh
89
105
  offckb accounts
@@ -110,6 +126,36 @@ Print account list, each account is funded with 42_000_000_00000000 capacity in
110
126
 
111
127
  Copy some private keys and visit http://localhost:1234 to play your first CKB Dapp!
112
128
 
129
+ ## Dapp Templates
130
+
131
+ `offckb` packs some basic minimal Dapp templates for you to learn and get started with. By running `offckb init`, you can select the different Dapp templates to quickly set up a local Dapp project targeting the local blockchain with built-in scripts and accounts.
132
+
133
+ The Dapp templates often involve interaction with some most useful smart contracts on CKB like xUDT/Spore/Omnilock. The best thing is those Dapp examples also come with detailed tutorial documents from [docs.nervos.org](https://docs.nervos.org/). The source codes of these templates are also maintained [here](https://github.com/nervosnetwork/docs.nervos.org/tree/develop-v2/examples).
134
+
135
+ ### View and transfer balance
136
+
137
+ A simple Dapp to check CKB balance and transfer CKB.
138
+
139
+ [Tutorial](https://nervos-ckb-docs-git-develop-v2-cryptape.vercel.app/docs/dapp/view-and-transfer-balance)
140
+
141
+ ### Write & read on-chain messages
142
+
143
+ A simple Dapp to issue your own token via XUDT scripts.
144
+
145
+ [Tutorial](https://nervos-ckb-docs-git-develop-v2-cryptape.vercel.app/docs/dapp/write-and-read-on-chain-message)
146
+
147
+ ### Issue custom token via xUDT scripts
148
+
149
+ A simple Dapp to store & retrieve data from a Cell.
150
+
151
+ [Tutorial](https://nervos-ckb-docs-git-develop-v2-cryptape.vercel.app/docs/dapp/issue-custom-token)
152
+
153
+ ### Create on-chain digital object via Spore protocol
154
+
155
+ A simple Dapp to create on-chain digital objects with spore scripts.
156
+
157
+ [Tutorial](https://nervos-ckb-docs-git-develop-v2-cryptape.vercel.app/docs/dapp/create-nft)
158
+
113
159
  ## Built-in scripts
114
160
 
115
161
  - [x] xUDT https://github.com/nervosnetwork/rfcs/pull/428
@@ -10,3 +10,8 @@ export declare const ckbFolderPath: string;
10
10
  export declare const ckbBinPath: string;
11
11
  export declare const accountTargetDir: string;
12
12
  export declare const minimalRequiredCKBVersion = "0.113.1";
13
+ export declare const dappTemplateGitRepoUserAndName = "nervosnetwork/docs.nervos.org";
14
+ export declare const dappTemplateGitUrl = "https://github.com/nervosnetwork/docs.nervos.org";
15
+ export declare const dappTemplateGitBranch = "develop-v2";
16
+ export declare const dappTemplateGitFolder = "examples";
17
+ export declare const dappTemplateGitSelectOptionFile = "options.json";
package/dist/cfg/const.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.minimalRequiredCKBVersion = exports.accountTargetDir = exports.ckbBinPath = exports.ckbFolderPath = exports.devnetDataPath = exports.devnetPath = exports.devnetSourcePath = exports.targetEnvironmentPath = exports.dappTemplatePath = exports.packageRootPath = exports.packageSrcPath = exports.currentExecPath = void 0;
26
+ exports.dappTemplateGitSelectOptionFile = exports.dappTemplateGitFolder = exports.dappTemplateGitBranch = exports.dappTemplateGitUrl = exports.dappTemplateGitRepoUserAndName = exports.minimalRequiredCKBVersion = exports.accountTargetDir = exports.ckbBinPath = exports.ckbFolderPath = exports.devnetDataPath = exports.devnetPath = exports.devnetSourcePath = exports.targetEnvironmentPath = exports.dappTemplatePath = exports.packageRootPath = exports.packageSrcPath = exports.currentExecPath = void 0;
27
27
  const path = __importStar(require("path"));
28
28
  // path
29
29
  exports.currentExecPath = process.cwd();
@@ -39,3 +39,9 @@ exports.ckbBinPath = path.resolve(exports.ckbFolderPath, 'ckb');
39
39
  exports.accountTargetDir = path.join(exports.packageRootPath, `account`);
40
40
  // Version
41
41
  exports.minimalRequiredCKBVersion = '0.113.1';
42
+ // url
43
+ exports.dappTemplateGitRepoUserAndName = 'nervosnetwork/docs.nervos.org';
44
+ exports.dappTemplateGitUrl = `https://github.com/${exports.dappTemplateGitRepoUserAndName}`;
45
+ exports.dappTemplateGitBranch = 'develop-v2';
46
+ exports.dappTemplateGitFolder = 'examples';
47
+ exports.dappTemplateGitSelectOptionFile = 'options.json';
package/dist/cli.js CHANGED
@@ -19,7 +19,6 @@ const init_chain_1 = require("./cmd/init-chain");
19
19
  const build_lumos_config_1 = require("./cmd/build-lumos-config");
20
20
  const init_1 = require("./cmd/init");
21
21
  const accounts_1 = require("./cmd/accounts");
22
- const select_1 = require("./cfg/select");
23
22
  const clean_1 = require("./cmd/clean");
24
23
  const version = require('../package.json').version;
25
24
  const program = new commander_1.Command();
@@ -32,7 +31,7 @@ program
32
31
  .description('init dapp project with lumos')
33
32
  .action((str) => __awaiter(void 0, void 0, void 0, function* () {
34
33
  const name = str !== null && str !== void 0 ? str : 'my-awesome-ckb-dapp';
35
- const template = yield (0, select_1.selectTemplate)();
34
+ const template = yield (0, init_1.selectTemplate)();
36
35
  return (0, init_1.init)(name, template);
37
36
  }));
38
37
  program.command('node').description('Use the CKB to start devnet').action(node_1.node);
@@ -59,6 +59,41 @@ export declare function devnetLumosConfigTemplate(cellBaseTxHashInGenesisBlock:
59
59
  INDEX: string;
60
60
  DEP_TYPE: string;
61
61
  };
62
+ SPORE: {
63
+ CODE_HASH: string;
64
+ HASH_TYPE: string;
65
+ TX_HASH: string;
66
+ INDEX: string;
67
+ DEP_TYPE: string;
68
+ };
69
+ SPORE_CLUSTER: {
70
+ CODE_HASH: string;
71
+ HASH_TYPE: string;
72
+ TX_HASH: string;
73
+ INDEX: string;
74
+ DEP_TYPE: string;
75
+ };
76
+ SPORE_CLUSTER_AGENT: {
77
+ CODE_HASH: string;
78
+ HASH_TYPE: string;
79
+ TX_HASH: string;
80
+ INDEX: string;
81
+ DEP_TYPE: string;
82
+ };
83
+ SPORE_CLUSTER_PROXY: {
84
+ CODE_HASH: string;
85
+ HASH_TYPE: string;
86
+ TX_HASH: string;
87
+ INDEX: string;
88
+ DEP_TYPE: string;
89
+ };
90
+ SPORE_LUA: {
91
+ CODE_HASH: string;
92
+ HASH_TYPE: string;
93
+ TX_HASH: string;
94
+ INDEX: string;
95
+ DEP_TYPE: string;
96
+ };
62
97
  };
63
98
  };
64
99
  export declare function buildLumosConfig(): Promise<void>;
@@ -79,6 +79,41 @@ function devnetLumosConfigTemplate(cellBaseTxHashInGenesisBlock, secondTxHashInG
79
79
  INDEX: '0x9',
80
80
  DEP_TYPE: 'code',
81
81
  },
82
+ SPORE: {
83
+ CODE_HASH: '0x7e8bf78a62232caa2f5d47e691e8db1a90d05e93dc6828ad3cb935c01ec6d208',
84
+ HASH_TYPE: 'data1',
85
+ TX_HASH: cellBaseTxHashInGenesisBlock,
86
+ INDEX: '0xa',
87
+ DEP_TYPE: 'code',
88
+ },
89
+ SPORE_CLUSTER: {
90
+ CODE_HASH: '0x7366a61534fa7c7e6225ecc0d828ea3b5366adec2b58206f2ee84995fe030075',
91
+ HASH_TYPE: 'data1',
92
+ TX_HASH: cellBaseTxHashInGenesisBlock,
93
+ INDEX: '0xb',
94
+ DEP_TYPE: 'code',
95
+ },
96
+ SPORE_CLUSTER_AGENT: {
97
+ CODE_HASH: '0xc986099b41d79ca1b2a56ce5874bcda8175440a17298ea5e2bbc3897736b8c21',
98
+ HASH_TYPE: 'data1',
99
+ TX_HASH: cellBaseTxHashInGenesisBlock,
100
+ INDEX: '0xc',
101
+ DEP_TYPE: 'code',
102
+ },
103
+ SPORE_CLUSTER_PROXY: {
104
+ CODE_HASH: '0xbe8b9ce3d05a32c4bb26fe71cd5fc1407ce91e3a8b9e8719be2ab072cef1454b',
105
+ HASH_TYPE: 'data1',
106
+ TX_HASH: cellBaseTxHashInGenesisBlock,
107
+ INDEX: '0xd',
108
+ DEP_TYPE: 'code',
109
+ },
110
+ SPORE_LUA: {
111
+ CODE_HASH: '0x94a9b875911ace20f1f0d063a26495d14e4b04e32fd218261bb747f34e71ae47',
112
+ HASH_TYPE: 'data1',
113
+ TX_HASH: cellBaseTxHashInGenesisBlock,
114
+ INDEX: '0xe',
115
+ DEP_TYPE: 'code',
116
+ },
82
117
  },
83
118
  };
84
119
  return devnetConfig;
@@ -1 +1,2 @@
1
1
  export declare function init(name: string, template: string): void;
2
+ export declare function selectTemplate(): Promise<string>;
package/dist/cmd/init.js CHANGED
@@ -1,16 +1,27 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
5
14
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.init = void 0;
15
+ exports.selectTemplate = exports.init = void 0;
7
16
  const const_1 = require("../cfg/const");
8
17
  const path_1 = __importDefault(require("path"));
9
18
  const util_1 = require("../util");
19
+ const select_1 = __importDefault(require("@inquirer/select"));
20
+ const util_2 = require("../util");
10
21
  function init(name, template) {
11
22
  const targetPath = path_1.default.resolve(const_1.currentExecPath, name);
12
- const sourcePath = path_1.default.resolve(const_1.dappTemplatePath, template);
13
- (0, util_1.copyFolderSync)(sourcePath, targetPath);
23
+ const dappTemplateFolderPath = `${const_1.dappTemplateGitFolder}/${template}`;
24
+ (0, util_1.gitCloneAndDownloadFolderSync)(const_1.dappTemplateGitUrl, const_1.dappTemplateGitBranch, dappTemplateFolderPath, targetPath);
14
25
  // add some common code files
15
26
  const ckbDotTs = path_1.default.resolve(const_1.dappTemplatePath, 'ckb.ts');
16
27
  const configJson = path_1.default.resolve(const_1.dappTemplatePath, 'config.json');
@@ -19,3 +30,14 @@ function init(name, template) {
19
30
  console.log(`init CKB dapp project: ${targetPath}`);
20
31
  }
21
32
  exports.init = init;
33
+ function selectTemplate() {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const opts = yield (0, util_2.loadTemplateOpts)();
36
+ const answer = yield (0, select_1.default)({
37
+ message: 'Select a Dapp template',
38
+ choices: opts,
39
+ });
40
+ return answer;
41
+ });
42
+ }
43
+ exports.selectTemplate = selectTemplate;
package/dist/util.d.ts CHANGED
@@ -4,3 +4,10 @@ export declare function copyFileSync(source: string, target: string): void;
4
4
  export declare function copyFilesWithExclusion(sourceDir: string, destinationDir: string, excludedFolders: string[]): Promise<void>;
5
5
  export declare function copyRecursive(source: string, destination: string, excludedFolders: string[]): Promise<void>;
6
6
  export declare function removeFolderSync(folderPath: string): void;
7
+ export declare function gitCloneAndDownloadFolderSync(repoUrl: string, branch: string, subFolderName: string, targetPath: string): void;
8
+ export interface TemplateOption {
9
+ name: string;
10
+ value: string;
11
+ description: string;
12
+ }
13
+ export declare function loadTemplateOpts(): Promise<Array<TemplateOption>>;
package/dist/util.js CHANGED
@@ -31,10 +31,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
31
31
  step((generator = generator.apply(thisArg, _arguments || [])).next());
32
32
  });
33
33
  };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
34
37
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.removeFolderSync = exports.copyRecursive = exports.copyFilesWithExclusion = exports.copyFileSync = exports.copyFolderSync = exports.isFolderExists = void 0;
38
+ exports.loadTemplateOpts = exports.gitCloneAndDownloadFolderSync = exports.removeFolderSync = exports.copyRecursive = exports.copyFilesWithExclusion = exports.copyFileSync = exports.copyFolderSync = exports.isFolderExists = void 0;
39
+ const child_process_1 = require("child_process");
36
40
  const fs = __importStar(require("fs"));
37
41
  const path = __importStar(require("path"));
42
+ const const_1 = require("./cfg/const");
43
+ const axios_1 = __importDefault(require("axios"));
44
+ const const_2 = require("./cfg/const");
38
45
  function isFolderExists(folderPath) {
39
46
  try {
40
47
  // Check if the path exists
@@ -139,3 +146,46 @@ function removeFolderSync(folderPath) {
139
146
  }
140
147
  }
141
148
  exports.removeFolderSync = removeFolderSync;
149
+ function gitCloneAndDownloadFolderSync(repoUrl, branch, subFolderName, targetPath) {
150
+ console.log('start cloning the dapp template..');
151
+ const tempFolder = path.resolve(const_1.dappTemplatePath, 'temp-clone-folder');
152
+ // Empty the temp folder if it exists
153
+ if (fs.existsSync(tempFolder)) {
154
+ fs.rmdirSync(tempFolder, { recursive: true });
155
+ }
156
+ // Create the temp folder
157
+ fs.mkdirSync(tempFolder, { recursive: true });
158
+ const cloneCommand = `
159
+ git clone -n --depth=1 --single-branch --branch ${branch} --filter=tree:0 \
160
+ ${repoUrl} ${tempFolder}
161
+ cd ${tempFolder}
162
+ git sparse-checkout set ${subFolderName}
163
+ git checkout
164
+ `;
165
+ (0, child_process_1.execSync)(cloneCommand);
166
+ // Ensure targetPath exists and is a directory
167
+ if (!fs.existsSync(targetPath) || !fs.statSync(targetPath).isDirectory()) {
168
+ fs.mkdirSync(targetPath, { recursive: true });
169
+ }
170
+ const source = path.resolve(tempFolder, subFolderName);
171
+ copyFolderSync(source, targetPath);
172
+ // Empty the temp folder if it exists
173
+ if (fs.existsSync(tempFolder)) {
174
+ fs.rmdirSync(tempFolder, { recursive: true });
175
+ }
176
+ console.log(`Folder ${subFolderName} downloaded successfully from ${repoUrl} and moved to ${targetPath}`);
177
+ }
178
+ exports.gitCloneAndDownloadFolderSync = gitCloneAndDownloadFolderSync;
179
+ function loadTemplateOpts() {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ const githubUrl = `https://raw.githubusercontent.com/${const_2.dappTemplateGitRepoUserAndName}/${const_2.dappTemplateGitBranch}/${const_2.dappTemplateGitFolder}/${const_2.dappTemplateGitSelectOptionFile}`;
182
+ try {
183
+ const response = yield axios_1.default.get(githubUrl);
184
+ return response.data;
185
+ }
186
+ catch (error) {
187
+ throw new Error(`Error fetching JSON: ${error.message}`);
188
+ }
189
+ });
190
+ }
191
+ exports.loadTemplateOpts = loadTemplateOpts;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@offckb/cli",
3
- "version": "0.1.0-rc5",
3
+ "version": "0.1.0-rc7",
4
4
  "description": "ckb development network for your first try",
5
5
  "author": "Retric Su <retric@cryptape.com>",
6
6
  "license": "MIT",
@@ -26,8 +26,8 @@
26
26
  "build": "tsc",
27
27
  "start": "ts-node-dev --transpile-only src/cli.ts",
28
28
  "clean": "rm -rf ./target",
29
- "lint": "eslint \"{src,templates}/**/*.ts\" \"{src,templates}/**/*.tsx\" --ignore-pattern 'node_modules/'",
30
- "lint:fix": "eslint \"{src,templates}/**/*.ts\" \"{src,templates}/**/*.tsx\" --ignore-pattern 'node_modules/' --fix",
29
+ "lint": "eslint \"src/**/*.ts\" \"templates/*.ts\" --ignore-pattern 'node_modules/'",
30
+ "lint:fix": "eslint \"src/**/*.ts\" \"templates/*.ts\" --ignore-pattern 'node_modules/' --fix",
31
31
  "fmt": "prettier --write '{src,templates,account}/**/*.{js,jsx,ts,tsx,md,json}'"
32
32
  },
33
33
  "husky": {
@@ -58,6 +58,41 @@
58
58
  "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
59
59
  "INDEX": "0x9",
60
60
  "DEP_TYPE": "code"
61
+ },
62
+ "SPORE": {
63
+ "CODE_HASH": "0x7e8bf78a62232caa2f5d47e691e8db1a90d05e93dc6828ad3cb935c01ec6d208",
64
+ "HASH_TYPE": "data1",
65
+ "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
66
+ "INDEX": "0xa",
67
+ "DEP_TYPE": "code"
68
+ },
69
+ "SPORE_CLUSTER": {
70
+ "CODE_HASH": "0x7366a61534fa7c7e6225ecc0d828ea3b5366adec2b58206f2ee84995fe030075",
71
+ "HASH_TYPE": "data1",
72
+ "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
73
+ "INDEX": "0xb",
74
+ "DEP_TYPE": "code"
75
+ },
76
+ "SPORE_CLUSTER_AGENT": {
77
+ "CODE_HASH": "0xc986099b41d79ca1b2a56ce5874bcda8175440a17298ea5e2bbc3897736b8c21",
78
+ "HASH_TYPE": "data1",
79
+ "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
80
+ "INDEX": "0xc",
81
+ "DEP_TYPE": "code"
82
+ },
83
+ "SPORE_CLUSTER_PROXY": {
84
+ "CODE_HASH": "0xbe8b9ce3d05a32c4bb26fe71cd5fc1407ce91e3a8b9e8719be2ab072cef1454b",
85
+ "HASH_TYPE": "data1",
86
+ "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
87
+ "INDEX": "0xd",
88
+ "DEP_TYPE": "code"
89
+ },
90
+ "SPORE_LUA": {
91
+ "CODE_HASH": "0x94a9b875911ace20f1f0d063a26495d14e4b04e32fd218261bb747f34e71ae47",
92
+ "HASH_TYPE": "data1",
93
+ "TX_HASH": "0x1dbed8dcfe0f18359c65c5e9546fd15cd69de73ea0a502345be30180649c9467",
94
+ "INDEX": "0xe",
95
+ "DEP_TYPE": "code"
61
96
  }
62
97
  }
63
98
  }
@@ -1 +0,0 @@
1
- export declare function selectTemplate(): Promise<string>;
@@ -1,51 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.selectTemplate = void 0;
16
- const prompts_1 = require("@inquirer/prompts");
17
- const select_1 = __importDefault(require("@inquirer/select"));
18
- function selectTemplate() {
19
- return __awaiter(this, void 0, void 0, function* () {
20
- const answer = yield (0, select_1.default)({
21
- message: 'Select a dapp template',
22
- choices: [
23
- {
24
- name: 'View and Transfer Balance',
25
- value: 'transfer',
26
- description: 'a simple dapp to check CKB balance and transfer CKB',
27
- },
28
- {
29
- name: 'Issue Token via XUDT scripts',
30
- value: 'xudt',
31
- description: 'a simple dapp to issue your own token via XUDT scripts',
32
- },
33
- new prompts_1.Separator(),
34
- {
35
- name: 'Issue Token With Max Supply Limit via Omnilock And XUDT scripts(coming)',
36
- value: 'xudt',
37
- description: 'a simple dapp to issue your own token with max supply limit via XUDT scripts',
38
- disabled: true,
39
- },
40
- {
41
- name: 'Create NFT With Spore scripts(coming)',
42
- value: 'xudt',
43
- description: 'a simple dapp to issue your own token with XUDT scripts',
44
- disabled: true,
45
- },
46
- ],
47
- });
48
- return answer;
49
- });
50
- }
51
- exports.selectTemplate = selectTemplate;
@@ -1,13 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>View and Transfer Balance</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script src="index.tsx" type="module"></script>
12
- </body>
13
- </html>
@@ -1,89 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import ReactDOM from 'react-dom';
3
- import { Script } from '@ckb-lumos/lumos';
4
- import { capacityOf, generateAccountFromPrivateKey, transfer } from './lib';
5
-
6
- const app = document.getElementById('root');
7
- ReactDOM.render(<App />, app);
8
-
9
- export function App() {
10
- const [privKey, setPrivKey] = useState('');
11
- const [fromAddr, setFromAddr] = useState('');
12
- const [fromLock, setFromLock] = useState<Script>();
13
- const [balance, setBalance] = useState('0');
14
-
15
- const [toAddr, setToAddr] = useState('');
16
- const [amount, setAmount] = useState('');
17
-
18
- useEffect(() => {
19
- const updateFromInfo = async () => {
20
- const { lockScript, address } = generateAccountFromPrivateKey(privKey);
21
- const capacity = await capacityOf(address);
22
- setFromAddr(address);
23
- setFromLock(lockScript);
24
- setBalance(capacity.toString());
25
- };
26
-
27
- if (privKey) {
28
- updateFromInfo();
29
- }
30
- }, [privKey]);
31
-
32
- const onInputPrivKey = (e: React.ChangeEvent<HTMLInputElement>) => {
33
- // Regular expression to match a valid private key with "0x" prefix
34
- const priv = e.target.value;
35
- const privateKeyRegex = /^0x[0-9a-fA-F]{64}$/;
36
-
37
- const isValid = privateKeyRegex.test(priv);
38
- if (isValid) {
39
- setPrivKey(priv);
40
- } else {
41
- alert(
42
- `Invalid private key: must start with 0x and 32 bytes length. Ensure you're using a valid private key from the offckb accounts list.`,
43
- );
44
- }
45
- };
46
-
47
- const enabled = +amount > 6100000000 && +balance > +amount && toAddr.length > 0;
48
- const amountTip =
49
- amount.length > 0 && +amount < 6100000000 ? (
50
- <span>
51
- amount must larger than 6,100,000,000(61 CKB), see{' '}
52
- <a href="https://medium.com/nervosnetwork/understanding-the-nervos-dao-and-cell-model-d68f38272c24">why</a>
53
- </span>
54
- ) : null;
55
-
56
- return (
57
- <div>
58
- <h1>View and Transfer Balance</h1>
59
- <label htmlFor="private-key">Private Key: </label>&nbsp;
60
- <input id="private-key" type="text" onChange={onInputPrivKey} />
61
- <ul>
62
- <li>CKB Address: {fromAddr}</li>
63
- <li>
64
- Current lock script:
65
- <pre>{JSON.stringify(fromLock, null, 2)}</pre>
66
- </li>
67
-
68
- <li>Total capacity: {(+balance).toLocaleString()}</li>
69
- </ul>
70
- <label htmlFor="to-address">Transfer to Address: </label>&nbsp;
71
- <input id="to-address" type="text" onChange={(e) => setToAddr(e.target.value)} />
72
- <br />
73
- <label htmlFor="amount">Amount</label>
74
- &nbsp;
75
- <input id="amount" type="number" onChange={(e) => setAmount(e.target.value)} />
76
- <small>Tx fee: 100,000 (0.001 CKB)</small>
77
- <br />
78
- <small style={{ color: 'red' }}>{amountTip}</small>
79
- <br />
80
- <br />
81
- <button
82
- disabled={!enabled}
83
- onClick={() => transfer({ amount, from: fromAddr, to: toAddr, privKey }).catch(alert)}
84
- >
85
- Transfer
86
- </button>
87
- </div>
88
- );
89
- }