@offckb/cli 0.3.0-rc6 → 0.3.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
@@ -34,6 +34,10 @@ There are BREAKING CHANGES between v0.2.x and v0.3.x, make sure to read the [mig
34
34
  - [Start the frontend project](#start-the-frontend-project)
35
35
  - [Debug a transaction](#debug-a-transaction)
36
36
  - [Generate Moleculec bindings](#generate-moleculec-bindings)
37
+ - [REPL Mode](#repl-mode)
38
+ - [Start the OffCKB REPL](#start-the-offckb-repl)
39
+ - [Build CKB transaction in REPL](#build-ckb-transaction-in-repl)
40
+ - [Get balance in REPL](#get-balance-in-repl)
37
41
  - [Config Setting](#config-setting)
38
42
  - [List All Settings](#list-all-settings)
39
43
  - [Set CKB version](#set-ckb-version)
@@ -50,7 +54,7 @@ There are BREAKING CHANGES between v0.2.x and v0.3.x, make sure to read the [mig
50
54
  npm install -g @offckb/cli
51
55
  ```
52
56
 
53
- _We recommand using [LTS](https://nodejs.org/en/download/package-manager) version of Node to run `offckb`_
57
+ _We recommend using [LTS](https://nodejs.org/en/download/package-manager) version of Node to run `offckb`_
54
58
 
55
59
  ## Usage
56
60
 
@@ -82,6 +86,7 @@ Commands:
82
86
  debug [options] CKB Debugger for development
83
87
  system-scripts [options] Output system scripts of the local devnet
84
88
  mol [options] Generate CKB Moleculec binding code for development
89
+ repl [options] A custom Nodejs REPL environment bundle for CKB.
85
90
  help [command] display help for command
86
91
  ```
87
92
 
@@ -310,6 +315,70 @@ If you have multiple `.mol` files, you can use a folder as the input and specify
310
315
  offckb mol --schema <path/to/mol/folder> --output-folder <path/to/output/folder> --lang <lang>
311
316
  ```
312
317
 
318
+ ## REPL Mode
319
+
320
+ OffCKB pack a custom Nodejs REPL with built-in variables and functions to help you develop CKB right in the terminal with minimal effort. This is suitable for simple script testing task when you don't want to write long and serious codes.
321
+
322
+ ### Start the OffCKB REPL
323
+
324
+ ```sh
325
+ offckb repl --network <devnet/testnet/mainnet, default: devnet>
326
+
327
+ Welcome to OffCKB REPL!
328
+ [[ Default Network: devnet, enableProxyRPC: false ]]
329
+ Type 'help()' to learn how to use.
330
+ OffCKB >
331
+ ```
332
+
333
+ Type `help()` to learn about the built-in variables and functions:
334
+
335
+ ```sh
336
+ OffCKB > help()
337
+
338
+ OffCKB Repl, a Nodejs REPL with CKB bundles.
339
+
340
+ Global Variables to use:
341
+ - ccc, cccA, imported from CKB Javascript SDK CCC
342
+ - client, a CCC client instance bundle with current network
343
+ - Client, a Wrap of CCC client class, you can build new client with
344
+ const myClient = Client.new('devnet' | 'testnet' | 'mainnet');
345
+ // or
346
+ const myClient = Client.fromUrl('<your rpc url>', 'devnet' | 'testnet' | 'mainnet');
347
+ - accounts, test accounts array from OffCKB
348
+ - networks, network information configs
349
+ - help, print this help message
350
+ ```
351
+
352
+ ### Build CKB transaction in REPL
353
+
354
+ ```sh
355
+ OffCKB > let amountInCKB = ccc.fixedPointFrom(63);
356
+ OffCKB > let tx = ccc.Transaction.from({
357
+ ... outputs: [
358
+ ... {
359
+ ... capacity: ccc.fixedPointFrom(amountInCKB),
360
+ ... lock: accounts[0].lockScript,
361
+ ... },
362
+ ... ],
363
+ ... });
364
+ OffCKB > let signer = new ccc.SignerCkbPrivateKey(client, accounts[0].privkey);
365
+ OffCKB > await tx.completeInputsByCapacity(signer);
366
+ 2
367
+ OffCKB > await tx.completeFeeBy(signer, 1000);
368
+ [ 0, true ]
369
+ OffCKB > await mySigner.sendTransaction(tx)
370
+ '0x50fbfa8c47907d6842a325e85e48d5da6917e16ca7e2253ec3bd5bcdf8da99ce'
371
+ ```
372
+
373
+ ### Get balance in REPL
374
+
375
+ ```sh
376
+ OffCKB > let myClient = Client.fromUrl(networks.testnet.rpc_url, 'testnet');
377
+ OffCKB > await myClient.getBalanceSingle(accounts[0].lockScript);
378
+ 60838485293944n
379
+ OffCKB >
380
+ ```
381
+
313
382
  ## Config Setting
314
383
 
315
384
  ### List All Settings
package/dist/cli.js CHANGED
@@ -54,6 +54,7 @@ const proxy_rpc_1 = require("./cmd/proxy-rpc");
54
54
  const mol_1 = require("./cmd/mol");
55
55
  const fs = __importStar(require("fs"));
56
56
  const transfer_all_1 = require("./cmd/transfer-all");
57
+ const repl_1 = require("./cmd/repl");
57
58
  const version = require('../package.json').version;
58
59
  const description = require('../package.json').description;
59
60
  // fix windows terminal encoding of simplified chinese text
@@ -186,6 +187,12 @@ program
186
187
  }
187
188
  return (0, mol_1.molSingleFile)(option.schema, option.output, option.lang);
188
189
  }));
190
+ program
191
+ .command('repl')
192
+ .description('A custom Nodejs REPL environment bundle for CKB.')
193
+ .option('--network <network>', 'Specify the network to deploy to', 'devnet')
194
+ .option('-r, --proxy-rpc', 'Use Proxy RPC to connect to blockchain')
195
+ .action(repl_1.repl);
189
196
  program.parse(process.argv);
190
197
  // If no command is specified, display help
191
198
  if (!process.argv.slice(2).length) {
@@ -0,0 +1,11 @@
1
+ import { ccc } from '@ckb-ccc/core';
2
+ import { Network, NetworkOption } from '../type/base';
3
+ export interface ReplProp extends NetworkOption {
4
+ proxyRpc?: boolean;
5
+ }
6
+ export declare function repl({ network, proxyRpc }: ReplProp): void;
7
+ export declare function initGlobalClientBuilder(): {
8
+ new: (network: Network) => ccc.ClientPublicTestnet | ccc.ClientPublicMainnet;
9
+ fromUrl: (rpcUrl: string, network: Network) => ccc.ClientPublicTestnet | ccc.ClientPublicMainnet;
10
+ };
11
+ export declare function printHelpText(): void;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.printHelpText = exports.initGlobalClientBuilder = exports.repl = void 0;
7
+ const repl_1 = require("repl");
8
+ const core_1 = require("@ckb-ccc/core");
9
+ const advanced_1 = require("@ckb-ccc/core/advanced");
10
+ const network_1 = require("../sdk/network");
11
+ const base_1 = require("../type/base");
12
+ const private_1 = require("../scripts/private");
13
+ const account_json_1 = __importDefault(require("../../account/account.json"));
14
+ const validator_1 = require("../util/validator");
15
+ function repl({ network = base_1.Network.devnet, proxyRpc = false }) {
16
+ (0, validator_1.validateNetworkOpt)(network);
17
+ console.log(
18
+ // Note remember update the CCC version since require CCC's package.json not work
19
+ `Welcome to OffCKB REPL!\n[[ Default Network: ${network}, enableProxyRPC: ${proxyRpc}, CCC SDK: 0.0.16-alpha.3 ]]\nType 'help()' to learn how to use.`);
20
+ const context = (0, repl_1.start)({
21
+ prompt: 'OffCKB > ',
22
+ ignoreUndefined: true,
23
+ useColors: true,
24
+ }).context;
25
+ context.ccc = core_1.ccc;
26
+ context.cccA = advanced_1.cccA;
27
+ context.networks = network_1.networks;
28
+ context.Client = initGlobalClientBuilder();
29
+ context.client = initGlobalClientBuilder().new(network);
30
+ context.accounts = account_json_1.default;
31
+ context.help = printHelpText;
32
+ }
33
+ exports.repl = repl;
34
+ function initGlobalClientBuilder() {
35
+ return {
36
+ new: (network) => {
37
+ return network === 'mainnet'
38
+ ? new core_1.ccc.ClientPublicMainnet()
39
+ : network === 'testnet'
40
+ ? new core_1.ccc.ClientPublicTestnet()
41
+ : new core_1.ccc.ClientPublicTestnet({
42
+ url: network_1.networks.devnet.rpc_url,
43
+ scripts: (0, private_1.buildCCCDevnetKnownScripts)(),
44
+ });
45
+ },
46
+ fromUrl: (rpcUrl, network) => {
47
+ return network === 'mainnet'
48
+ ? new core_1.ccc.ClientPublicMainnet({ url: rpcUrl })
49
+ : network === 'testnet'
50
+ ? new core_1.ccc.ClientPublicTestnet({ url: rpcUrl })
51
+ : new core_1.ccc.ClientPublicTestnet({
52
+ url: rpcUrl,
53
+ scripts: (0, private_1.buildCCCDevnetKnownScripts)(),
54
+ });
55
+ },
56
+ };
57
+ }
58
+ exports.initGlobalClientBuilder = initGlobalClientBuilder;
59
+ function printHelpText() {
60
+ return console.log(`
61
+ OffCKB Repl, a Nodejs REPL with CKB bundles.
62
+
63
+ Global Variables to use:
64
+ - ccc, cccA, imported from CKB Javascript SDK CCC
65
+ - client, a CCC client instance bundle with current network
66
+ - Client, a Wrap of CCC client class, you can build new client with
67
+ const myClient = Client.new('devnet' | 'testnet' | 'mainnet');
68
+ // or
69
+ const myClient = Client.fromUrl('<your rpc url>', 'devnet' | 'testnet' | 'mainnet');
70
+ - accounts, test accounts array from OffCKB
71
+ - networks, network information configs
72
+ - help, print this help message
73
+ `);
74
+ }
75
+ exports.printHelpText = printHelpText;
@@ -46,6 +46,7 @@ const tar = __importStar(require("tar"));
46
46
  const request_1 = require("../util/request");
47
47
  const setting_1 = require("../cfg/setting");
48
48
  const encoding_1 = require("../util/encoding");
49
+ const cpu_features_1 = __importDefault(require("cpu-features"));
49
50
  function installCKBBinary(version) {
50
51
  return __awaiter(this, void 0, void 0, function* () {
51
52
  const ckbBinPath = (0, setting_1.getCKBBinaryPath)(version);
@@ -67,18 +68,16 @@ function installCKBBinary(version) {
67
68
  exports.installCKBBinary = installCKBBinary;
68
69
  function downloadCKBBinaryAndUnzip(version) {
69
70
  return __awaiter(this, void 0, void 0, function* () {
70
- const arch = getArch();
71
- const osname = getOS();
72
- const ext = getExtension();
73
- const ckbVersionOSName = `ckb_v${version}_${arch}-${osname}`;
71
+ const ckbPackageName = buildCKBGithubReleasePackageName(version);
74
72
  try {
75
- const tempFilePath = path.join(os_1.default.tmpdir(), `${ckbVersionOSName}.${ext}`);
73
+ const ext = getExtension();
74
+ const tempFilePath = path.join(os_1.default.tmpdir(), `${ckbPackageName}.${ext}`);
76
75
  yield downloadAndSaveCKBBinary(version, tempFilePath);
77
76
  // Unzip the file
78
77
  const extractDir = path.join((0, setting_1.readSettings)().bins.downloadPath, `ckb_v${version}`);
79
78
  yield unZipFile(tempFilePath, extractDir, ext === 'tar.gz');
80
79
  // Install the extracted files
81
- const sourcePath = path.join(extractDir, ckbVersionOSName);
80
+ const sourcePath = path.join(extractDir, ckbPackageName);
82
81
  const targetPath = (0, setting_1.getCKBBinaryInstallPath)(version);
83
82
  if (fs.existsSync(targetPath)) {
84
83
  fs.rmdirSync(targetPath, { recursive: true });
@@ -97,6 +96,7 @@ exports.downloadCKBBinaryAndUnzip = downloadCKBBinaryAndUnzip;
97
96
  function downloadAndSaveCKBBinary(version, tempFilePath) {
98
97
  return __awaiter(this, void 0, void 0, function* () {
99
98
  const downloadURL = buildDownloadUrl(version);
99
+ console.log(`downloading ${downloadURL} ..`);
100
100
  const response = yield request_1.Request.send(downloadURL);
101
101
  const arrayBuffer = yield response.arrayBuffer();
102
102
  fs.writeFileSync(tempFilePath, Buffer.from(arrayBuffer));
@@ -189,10 +189,38 @@ function getExtension() {
189
189
  }
190
190
  return 'zip';
191
191
  }
192
- function buildDownloadUrl(version, opt = {}) {
192
+ function isPortable() {
193
+ const features = (0, cpu_features_1.default)();
194
+ if (features.arch === 'x86') {
195
+ const flags = features.flags;
196
+ // if lacks any of the following instruction, use portable binary
197
+ return !(flags.avx2 && flags.sse4_2 && flags.bmi2 && flags.pclmulqdq);
198
+ }
199
+ return false;
200
+ }
201
+ function buildCKBGithubReleasePackageName(version, opt = {}) {
202
+ const os = opt.os || getOS();
203
+ const arch = opt.arch || getArch();
204
+ if (isPortable()) {
205
+ return `ckb_v${version}_${arch}-${os}-portable`;
206
+ }
207
+ else {
208
+ return `ckb_v${version}_${arch}-${os}`;
209
+ }
210
+ }
211
+ function buildCKBGithubReleasePackageNameWithExtension(version, opt = {}) {
193
212
  const os = opt.os || getOS();
194
213
  const arch = opt.arch || getArch();
195
214
  const extension = opt.ext || getExtension();
196
- return `https://github.com/nervosnetwork/ckb/releases/download/v${version}/ckb_v${version}_${arch}-${os}.${extension}`;
215
+ if (isPortable()) {
216
+ return `ckb_v${version}_${arch}-${os}-portable.${extension}`;
217
+ }
218
+ else {
219
+ return `ckb_v${version}_${arch}-${os}.${extension}`;
220
+ }
221
+ }
222
+ function buildDownloadUrl(version, opt = {}) {
223
+ const fullPackageName = buildCKBGithubReleasePackageNameWithExtension(version, opt);
224
+ return `https://github.com/nervosnetwork/ckb/releases/download/v${version}/${fullPackageName}`;
197
225
  }
198
226
  exports.buildDownloadUrl = buildDownloadUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@offckb/cli",
3
- "version": "0.3.0-rc6",
3
+ "version": "0.3.0-rc7",
4
4
  "description": "ckb development network for your first try",
5
5
  "author": "CKB EcoFund",
6
6
  "license": "MIT",
@@ -46,6 +46,7 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/adm-zip": "^0.5.5",
49
+ "@types/cpu-features": "^0.0.3",
49
50
  "@types/node": "^20.11.19",
50
51
  "@types/node-fetch": "^2.6.11",
51
52
  "@types/semver": "^7.5.7",
@@ -68,6 +69,7 @@
68
69
  "child_process": "^1.0.2",
69
70
  "ckb-transaction-dumper": "^0.4.0",
70
71
  "commander": "^12.0.0",
72
+ "cpu-features": "^0.0.10",
71
73
  "http-proxy": "^1.18.1",
72
74
  "https-proxy-agent": "^7.0.5",
73
75
  "node-fetch": "2",