@offckb/cli 0.4.1 ā 0.4.2-canary-1af067f.0
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 +16 -7
- package/build/index.js +61 -52
- package/ckb/devnet/specs/ckb_js_vm +0 -0
- package/package.json +1 -1
- package/templates/v4/base-template/README.md.template +14 -0
- package/templates/v4/base-template/scripts/build-all.js +4 -4
- package/templates/v4/base-template/scripts/build-contract.js +16 -5
package/README.md
CHANGED
|
@@ -24,12 +24,12 @@ There are BREAKING CHANGES between v0.3.x and v0.4.x, make sure to read the [mig
|
|
|
24
24
|
- [Install](#install)
|
|
25
25
|
- [Usage](#usage)
|
|
26
26
|
- [Get started](#get-started)
|
|
27
|
-
- [Run a Local CKB Devnet](#running-ckb)
|
|
28
|
-
- [Create a
|
|
29
|
-
- [Deploy
|
|
30
|
-
- [Debug
|
|
31
|
-
- [Explore
|
|
32
|
-
- [Tweak Devnet Config](#tweak-devnet-config)
|
|
27
|
+
- [1. Run a Local CKB Devnet {#running-ckb}](#1-run-a-local-ckb-devnet-running-ckb)
|
|
28
|
+
- [2. Create a New Contract Project {#create-project}](#2-create-a-new-contract-project-create-project)
|
|
29
|
+
- [3. Deploy Your Contract {#deploy-contract}](#3-deploy-your-contract-deploy-contract)
|
|
30
|
+
- [4. Debug Your Contract {#debug-contract}](#4-debug-your-contract-debug-contract)
|
|
31
|
+
- [5. Explore Built-in Scripts {#explore-scripts}](#5-explore-built-in-scripts-explore-scripts)
|
|
32
|
+
- [6. Tweak Devnet Config {#tweak-devnet-config}](#6-tweak-devnet-config-tweak-devnet-config)
|
|
33
33
|
- [Config Setting](#config-setting)
|
|
34
34
|
- [List All Settings](#list-all-settings)
|
|
35
35
|
- [Set CKB version](#set-ckb-version)
|
|
@@ -107,6 +107,15 @@ Or set a default version globally:
|
|
|
107
107
|
offckb config set ckb-version 0.201.0
|
|
108
108
|
offckb node
|
|
109
109
|
```
|
|
110
|
+
|
|
111
|
+
Or specify the path to your locally compiled CKB binary:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
offckb node --binary-path /path/to/your/ckb/binary
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
When using `--binary-path`, it will ignore the specified version and network, and only work for devnet.
|
|
118
|
+
|
|
110
119
|
**RPC & Proxy RPC**
|
|
111
120
|
|
|
112
121
|
When the Devnet starts:
|
|
@@ -125,7 +134,7 @@ Using a proxy RPC server for Testnet/Mainnet is especially helpful for debugging
|
|
|
125
134
|
|
|
126
135
|
### 2. Create a New Contract Project {#create-project}
|
|
127
136
|
|
|
128
|
-
Generate a ready-to-use project in JS/TS using templates:
|
|
137
|
+
Generate a ready-to-use smart-contract project in JS/TS using templates:
|
|
129
138
|
```sh
|
|
130
139
|
offckb create <your-project-name> -c <your-contract-name>
|
|
131
140
|
```
|
package/build/index.js
CHANGED
|
@@ -332,8 +332,9 @@ program
|
|
|
332
332
|
.command('node [CKB-Version]')
|
|
333
333
|
.description('Use the CKB to start devnet')
|
|
334
334
|
.option('--network <network>', 'Specify the network to deploy to', 'devnet')
|
|
335
|
+
.option('-b, --binary-path <binaryPath>', 'Specify the CKB binary path to use, only for devnet, when set, will ignore version and network')
|
|
335
336
|
.action((version, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
336
|
-
return (0, node_1.startNode)({ version, network: options.network });
|
|
337
|
+
return (0, node_1.startNode)({ version, network: options.network, binaryPath: options.binaryPath });
|
|
337
338
|
}));
|
|
338
339
|
program
|
|
339
340
|
.command('create [project-name]')
|
|
@@ -1286,10 +1287,13 @@ const encoding_1 = __nccwpck_require__(6851);
|
|
|
1286
1287
|
const rpc_proxy_1 = __nccwpck_require__(46589);
|
|
1287
1288
|
const base_1 = __nccwpck_require__(69951);
|
|
1288
1289
|
const logger_1 = __nccwpck_require__(65370);
|
|
1289
|
-
function startNode({ version, network = base_1.Network.devnet }) {
|
|
1290
|
+
function startNode({ version, network = base_1.Network.devnet, binaryPath }) {
|
|
1291
|
+
if (binaryPath && network !== base_1.Network.devnet) {
|
|
1292
|
+
logger_1.logger.warn('Custom binaryPath is only supported for devnet. The provided binaryPath will be ignored.');
|
|
1293
|
+
}
|
|
1290
1294
|
switch (network) {
|
|
1291
1295
|
case base_1.Network.devnet:
|
|
1292
|
-
return nodeDevnet({ version });
|
|
1296
|
+
return nodeDevnet({ version, binaryPath });
|
|
1293
1297
|
case base_1.Network.testnet:
|
|
1294
1298
|
return nodeTestnet();
|
|
1295
1299
|
case base_1.Network.mainnet:
|
|
@@ -1299,13 +1303,20 @@ function startNode({ version, network = base_1.Network.devnet }) {
|
|
|
1299
1303
|
}
|
|
1300
1304
|
}
|
|
1301
1305
|
function nodeDevnet(_a) {
|
|
1302
|
-
return __awaiter(this, arguments, void 0, function* ({ version }) {
|
|
1306
|
+
return __awaiter(this, arguments, void 0, function* ({ version, binaryPath }) {
|
|
1303
1307
|
var _b, _c;
|
|
1304
1308
|
const settings = (0, setting_1.readSettings)();
|
|
1305
1309
|
const ckbVersion = version || settings.bins.defaultCKBVersion;
|
|
1306
|
-
|
|
1310
|
+
let ckbBinPath = '';
|
|
1311
|
+
if (binaryPath) {
|
|
1312
|
+
ckbBinPath = (0, encoding_1.encodeBinPathForTerminal)(binaryPath);
|
|
1313
|
+
logger_1.logger.info(`Using custom CKB binary path: ${ckbBinPath}`);
|
|
1314
|
+
}
|
|
1315
|
+
else {
|
|
1316
|
+
yield (0, install_1.installCKBBinary)(ckbVersion);
|
|
1317
|
+
ckbBinPath = (0, encoding_1.encodeBinPathForTerminal)((0, setting_1.getCKBBinaryPath)(ckbVersion));
|
|
1318
|
+
}
|
|
1307
1319
|
yield (0, init_chain_1.initChainIfNeeded)();
|
|
1308
|
-
const ckbBinPath = (0, encoding_1.encodeBinPathForTerminal)((0, setting_1.getCKBBinaryPath)(ckbVersion));
|
|
1309
1320
|
const devnetConfigPath = (0, encoding_1.encodeBinPathForTerminal)(settings.devnet.configPath);
|
|
1310
1321
|
const ckbCmd = `${ckbBinPath} run -C ${devnetConfigPath}`;
|
|
1311
1322
|
const minerCmd = `${ckbBinPath} miner -C ${devnetConfigPath}`;
|
|
@@ -1471,7 +1482,7 @@ function systemCellToScriptInfo({ cell, depType, depGroup, extraCellDeps, }) {
|
|
|
1471
1482
|
}
|
|
1472
1483
|
return {
|
|
1473
1484
|
codeHash: (cell.type_hash || cell.data_hash),
|
|
1474
|
-
hashType: cell.type_hash ? 'type' : '
|
|
1485
|
+
hashType: cell.type_hash ? 'type' : 'data2',
|
|
1475
1486
|
cellDeps,
|
|
1476
1487
|
};
|
|
1477
1488
|
}
|
|
@@ -1495,7 +1506,7 @@ function systemCellToScriptInfo({ cell, depType, depGroup, extraCellDeps, }) {
|
|
|
1495
1506
|
}
|
|
1496
1507
|
return {
|
|
1497
1508
|
codeHash: (cell.type_hash || cell.data_hash),
|
|
1498
|
-
hashType: cell.type_hash ? 'type' : '
|
|
1509
|
+
hashType: cell.type_hash ? 'type' : 'data2',
|
|
1499
1510
|
cellDeps,
|
|
1500
1511
|
};
|
|
1501
1512
|
}
|
|
@@ -2797,7 +2808,7 @@ exports.TESTNET_SYSTEM_SCRIPTS = {
|
|
|
2797
2808
|
name: 'secp256k1_blake160_multisig_all_v2',
|
|
2798
2809
|
script: {
|
|
2799
2810
|
codeHash: '0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29',
|
|
2800
|
-
hashType: '
|
|
2811
|
+
hashType: 'data2',
|
|
2801
2812
|
cellDeps: [
|
|
2802
2813
|
{
|
|
2803
2814
|
cellDep: {
|
|
@@ -2921,7 +2932,7 @@ exports.MAINNET_SYSTEM_SCRIPTS = {
|
|
|
2921
2932
|
name: 'secp256k1_blake160_multisig_all_v2',
|
|
2922
2933
|
script: {
|
|
2923
2934
|
codeHash: '0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29',
|
|
2924
|
-
hashType: '
|
|
2935
|
+
hashType: 'data2',
|
|
2925
2936
|
cellDeps: [
|
|
2926
2937
|
{
|
|
2927
2938
|
cellDep: {
|
|
@@ -3025,7 +3036,7 @@ function getScriptInfoFrom(recipe) {
|
|
|
3025
3036
|
const isDepCode = recipe.depGroupRecipes.length > 0;
|
|
3026
3037
|
const scriptsInfo = {
|
|
3027
3038
|
codeHash: (firstCell.typeId ? firstCell.typeId : firstCell.dataHash),
|
|
3028
|
-
hashType: firstCell.typeId ? 'type' : '
|
|
3039
|
+
hashType: firstCell.typeId ? 'type' : 'data2',
|
|
3029
3040
|
cellDeps: !isDepCode
|
|
3030
3041
|
? [
|
|
3031
3042
|
{
|
|
@@ -3373,16 +3384,32 @@ exports.networks = {
|
|
|
3373
3384
|
"use strict";
|
|
3374
3385
|
|
|
3375
3386
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3376
|
-
exports.
|
|
3377
|
-
exports.
|
|
3387
|
+
exports.REQUIRED_FILES = exports.PACKAGE_JSON_CONFIG = void 0;
|
|
3388
|
+
exports.PACKAGE_JSON_CONFIG = {
|
|
3389
|
+
version: '0.1.0',
|
|
3390
|
+
description: 'CKB JavaScript Smart Contract project',
|
|
3391
|
+
private: true,
|
|
3392
|
+
type: 'module',
|
|
3393
|
+
scripts: {
|
|
3394
|
+
'build:contract': 'node scripts/build-contract.js',
|
|
3395
|
+
'build:contract:debug': 'node scripts/build-contract.js --debug',
|
|
3396
|
+
build: 'node scripts/build-all.js',
|
|
3397
|
+
'build:debug': 'node scripts/build-all.js --debug',
|
|
3398
|
+
deploy: 'node scripts/build-all.js && node scripts/deploy.js',
|
|
3399
|
+
'deploy:debug': 'node scripts/build-all.js --debug && node scripts/deploy.js',
|
|
3400
|
+
test: 'node scripts/build-all.js && jest',
|
|
3401
|
+
'add-contract': 'node scripts/add-contract.js',
|
|
3402
|
+
clean: 'rimraf dist',
|
|
3403
|
+
format: 'prettier --write .',
|
|
3404
|
+
},
|
|
3378
3405
|
dependencies: {
|
|
3379
3406
|
'@ckb-js-std/bindings': '~1.0.0',
|
|
3380
3407
|
'@ckb-js-std/core': '~1.0.0',
|
|
3381
3408
|
dotenv: '^17.2.1',
|
|
3382
3409
|
},
|
|
3383
3410
|
devDependencies: {
|
|
3384
|
-
'ckb-testtool': '1.0.
|
|
3385
|
-
'@ckb-ccc/core': '1.
|
|
3411
|
+
'ckb-testtool': '1.0.5',
|
|
3412
|
+
'@ckb-ccc/core': '1.12.2', // lock to version compatible with ckb-testtool
|
|
3386
3413
|
esbuild: '~0.25.8',
|
|
3387
3414
|
jest: '~29.7.0',
|
|
3388
3415
|
prettier: '^3.5.3',
|
|
@@ -3395,25 +3422,16 @@ exports.TEMPLATE_CONFIG = {
|
|
|
3395
3422
|
'@types/jest': '~29.5.14',
|
|
3396
3423
|
},
|
|
3397
3424
|
};
|
|
3398
|
-
exports.
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
'deployment/README.md.template',
|
|
3409
|
-
'env.example.template',
|
|
3410
|
-
'env.template',
|
|
3411
|
-
],
|
|
3412
|
-
conditionalFiles: {
|
|
3413
|
-
typescript: ['tsconfig.json.template', 'tsconfig.base.json.template'],
|
|
3414
|
-
javascript: [],
|
|
3415
|
-
},
|
|
3416
|
-
};
|
|
3425
|
+
exports.REQUIRED_FILES = [
|
|
3426
|
+
'package.json.template',
|
|
3427
|
+
'jest.config.cjs.template',
|
|
3428
|
+
'gitignore.template',
|
|
3429
|
+
'README.md.template',
|
|
3430
|
+
'deployment/scripts.json.template',
|
|
3431
|
+
'deployment/README.md.template',
|
|
3432
|
+
'env.example.template',
|
|
3433
|
+
'env.template',
|
|
3434
|
+
];
|
|
3417
3435
|
|
|
3418
3436
|
|
|
3419
3437
|
/***/ }),
|
|
@@ -3661,7 +3679,7 @@ class TemplateProcessor {
|
|
|
3661
3679
|
return false;
|
|
3662
3680
|
}
|
|
3663
3681
|
// Always include required files
|
|
3664
|
-
if (config_1.
|
|
3682
|
+
if (config_1.REQUIRED_FILES.some((reqFile) => relativePath.includes(reqFile))) {
|
|
3665
3683
|
return true;
|
|
3666
3684
|
}
|
|
3667
3685
|
// Handle language-specific jest config files
|
|
@@ -3705,25 +3723,16 @@ class TemplateProcessor {
|
|
|
3705
3723
|
generatePackageJson(context) {
|
|
3706
3724
|
const basePackageJson = {
|
|
3707
3725
|
name: context.projectName,
|
|
3708
|
-
version:
|
|
3709
|
-
description:
|
|
3710
|
-
private:
|
|
3711
|
-
type:
|
|
3712
|
-
scripts:
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
test: 'node scripts/build-all.js && jest',
|
|
3716
|
-
'add-contract': 'node scripts/add-contract.js',
|
|
3717
|
-
deploy: 'node scripts/build-all.js && node scripts/deploy.js',
|
|
3718
|
-
clean: 'rimraf dist',
|
|
3719
|
-
format: 'prettier --write .',
|
|
3720
|
-
},
|
|
3721
|
-
dependencies: config_1.TEMPLATE_CONFIG.dependencies,
|
|
3722
|
-
devDependencies: Object.assign({}, config_1.TEMPLATE_CONFIG.devDependencies),
|
|
3726
|
+
version: config_1.PACKAGE_JSON_CONFIG.version,
|
|
3727
|
+
description: config_1.PACKAGE_JSON_CONFIG.description,
|
|
3728
|
+
private: config_1.PACKAGE_JSON_CONFIG.private,
|
|
3729
|
+
type: config_1.PACKAGE_JSON_CONFIG.type,
|
|
3730
|
+
scripts: config_1.PACKAGE_JSON_CONFIG.scripts,
|
|
3731
|
+
dependencies: config_1.PACKAGE_JSON_CONFIG.dependencies,
|
|
3732
|
+
devDependencies: Object.assign({}, config_1.PACKAGE_JSON_CONFIG.devDependencies),
|
|
3723
3733
|
};
|
|
3724
|
-
// Add TypeScript dependencies if needed
|
|
3725
3734
|
if (context.language === 'typescript') {
|
|
3726
|
-
Object.assign(basePackageJson.devDependencies, config_1.
|
|
3735
|
+
Object.assign(basePackageJson.devDependencies, config_1.PACKAGE_JSON_CONFIG.typescriptDevDeps);
|
|
3727
3736
|
}
|
|
3728
3737
|
return basePackageJson;
|
|
3729
3738
|
}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -56,6 +56,15 @@ Build a specific contract:
|
|
|
56
56
|
{{PACKAGE_MANAGER}} run build:contract hello-world
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Build with debug version:
|
|
60
|
+
```bash
|
|
61
|
+
{{PACKAGE_MANAGER}} run build:debug
|
|
62
|
+
```
|
|
63
|
+
or for specific contract with debug enabled:
|
|
64
|
+
```bash
|
|
65
|
+
{{PACKAGE_MANAGER}} run build:contract:debug hello-world
|
|
66
|
+
```
|
|
67
|
+
|
|
59
68
|
### Running Tests
|
|
60
69
|
|
|
61
70
|
Run all tests:
|
|
@@ -106,9 +115,12 @@ Tests use the `ckb-testtool` framework to simulate CKB blockchain execution. Eac
|
|
|
106
115
|
|
|
107
116
|
- `build` - Build all contracts
|
|
108
117
|
- `build:contract <name>` - Build a specific contract
|
|
118
|
+
- `build:debug` - Build all contracts with debug version
|
|
119
|
+
- `build:contract:debug <name>` - Build a specific contract with debug version
|
|
109
120
|
- `test` - Run all tests
|
|
110
121
|
- `add-contract <name>` - Add a new contract
|
|
111
122
|
- `deploy` - Deploy contracts to CKB network
|
|
123
|
+
- `deploy:debug` - Deploy contracts with debug version to CKB network
|
|
112
124
|
- `clean` - Remove all build outputs
|
|
113
125
|
- `format` - Format code with Prettier
|
|
114
126
|
|
|
@@ -129,6 +141,8 @@ Deploy your contracts to CKB networks using the built-in deploy script:
|
|
|
129
141
|
{{PACKAGE_MANAGER}} run deploy -- --network mainnet
|
|
130
142
|
```
|
|
131
143
|
|
|
144
|
+
Note that you can change the `run deploy` to `run deploy:debug` to deploy the debug version of your smart contracts.
|
|
145
|
+
|
|
132
146
|
### Advanced Options
|
|
133
147
|
|
|
134
148
|
```bash
|
|
@@ -4,7 +4,7 @@ import fs from 'fs';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
6
|
|
|
7
|
-
function buildAllContracts() {
|
|
7
|
+
function buildAllContracts(isDebug = false) {
|
|
8
8
|
const contractsDir = path.join(process.cwd(), 'contracts');
|
|
9
9
|
|
|
10
10
|
if (!fs.existsSync(contractsDir)) {
|
|
@@ -27,8 +27,8 @@ function buildAllContracts() {
|
|
|
27
27
|
for (const contractName of contracts) {
|
|
28
28
|
console.log(`\nš¦ Building contract: ${contractName}`);
|
|
29
29
|
try {
|
|
30
|
-
execSync(`node scripts/build-contract.js ${contractName}`, { stdio: 'inherit' });
|
|
31
|
-
console.log(`ā
Successfully built: ${contractName}`);
|
|
30
|
+
execSync(`node scripts/build-contract.js ${contractName} ${isDebug ? '--debug' : ''}`, { stdio: 'inherit' });
|
|
31
|
+
console.log(`ā
Successfully built: ${contractName} with ${isDebug ? 'debug' : 'release'} version`);
|
|
32
32
|
} catch (error) {
|
|
33
33
|
console.error(`ā Failed to build: ${contractName}`);
|
|
34
34
|
console.error(error.message);
|
|
@@ -39,4 +39,4 @@ function buildAllContracts() {
|
|
|
39
39
|
console.log(`\nš All contracts built successfully!`);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
buildAllContracts();
|
|
42
|
+
buildAllContracts(process.argv.includes('--debug'));
|
|
@@ -4,7 +4,7 @@ import { execSync } from 'child_process';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
|
|
7
|
-
function buildContract(contractName) {
|
|
7
|
+
function buildContract(contractName, isDebug = false) {
|
|
8
8
|
if (!contractName) {
|
|
9
9
|
console.error('Usage: node build-contract.js <contract-name>');
|
|
10
10
|
process.exit(1);
|
|
@@ -50,14 +50,23 @@ function buildContract(contractName) {
|
|
|
50
50
|
// }
|
|
51
51
|
|
|
52
52
|
// Step 2: Bundle with esbuild
|
|
53
|
-
console.log(
|
|
53
|
+
console.log(` š¦ Bundling with esbuild with ${isDebug ? 'debug' : 'release'} settings...`);
|
|
54
|
+
const debugParams = [
|
|
55
|
+
'--sourcemap=external',
|
|
56
|
+
'--sources-content',
|
|
57
|
+
'--keep-names',
|
|
58
|
+
'--minify=false',
|
|
59
|
+
'--define:DEBUG=true',
|
|
60
|
+
'--loader:.map=json',
|
|
61
|
+
];
|
|
62
|
+
const releaseParams = ['--minify'];
|
|
54
63
|
const esbuildCmd = [
|
|
55
64
|
'./node_modules/.bin/esbuild',
|
|
56
65
|
'--platform=neutral',
|
|
57
|
-
'--minify',
|
|
58
66
|
'--bundle',
|
|
59
67
|
'--external:@ckb-js-std/bindings',
|
|
60
68
|
'--target=es2022',
|
|
69
|
+
...(isDebug ? debugParams : releaseParams),
|
|
61
70
|
srcFile,
|
|
62
71
|
`--outfile=${outputJsFile}`,
|
|
63
72
|
].join(' ');
|
|
@@ -87,5 +96,7 @@ function buildContract(contractName) {
|
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
// Get contract name from command line arguments
|
|
90
|
-
const
|
|
91
|
-
|
|
99
|
+
const isDebug = process.argv.includes('--debug');
|
|
100
|
+
const args = process.argv.slice(2).filter((arg) => arg !== '--debug');
|
|
101
|
+
const contractName = args[0];
|
|
102
|
+
buildContract(contractName, isDebug);
|