@offckb/cli 0.1.0-rc6 → 0.1.0-rc8
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 +35 -0
- package/dist/cfg/const.d.ts +5 -0
- package/dist/cfg/const.js +7 -1
- package/dist/cli.js +1 -2
- package/dist/cmd/build-lumos-config.d.ts +35 -0
- package/dist/cmd/build-lumos-config.js +35 -0
- package/dist/cmd/clean.js +5 -1
- package/dist/cmd/init.d.ts +1 -0
- package/dist/cmd/init.js +25 -3
- package/dist/cmd/install.d.ts +14 -0
- package/dist/cmd/install.js +78 -16
- package/dist/util.d.ts +8 -1
- package/dist/util.js +73 -17
- package/package.json +6 -4
- package/templates/config.json +35 -0
- package/dist/cfg/select.d.ts +0 -1
- package/dist/cfg/select.js +0 -51
- package/templates/transfer/index.html +0 -13
- package/templates/transfer/index.tsx +0 -89
- package/templates/transfer/lib.ts +0 -153
- package/templates/transfer/package.json +0 -29
- package/templates/transfer/tsconfig.json +0 -10
- package/templates/transfer/yarn.lock +0 -2315
- package/templates/xudt/index.html +0 -13
- package/templates/xudt/index.tsx +0 -212
- package/templates/xudt/lib.ts +0 -252
- package/templates/xudt/package.json +0 -29
- package/templates/xudt/scheme.ts +0 -27
- package/templates/xudt/tsconfig.json +0 -10
- package/templates/xudt/util.ts +0 -66
- package/templates/xudt/yarn.lock +0 -2315
package/dist/cfg/select.js
DELETED
|
@@ -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>
|
|
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>
|
|
71
|
-
<input id="to-address" type="text" onChange={(e) => setToAddr(e.target.value)} />
|
|
72
|
-
<br />
|
|
73
|
-
<label htmlFor="amount">Amount</label>
|
|
74
|
-
|
|
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
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { bytes } from '@ckb-lumos/codec';
|
|
2
|
-
import { helpers, Address, Script, hd, config, Cell, commons, WitnessArgs, BI } from '@ckb-lumos/lumos';
|
|
3
|
-
import { values, blockchain } from '@ckb-lumos/base';
|
|
4
|
-
import { indexer, lumosConfig, rpc } from './ckb';
|
|
5
|
-
const { ScriptValue } = values;
|
|
6
|
-
|
|
7
|
-
config.initializeConfig(lumosConfig);
|
|
8
|
-
|
|
9
|
-
type Account = {
|
|
10
|
-
lockScript: Script;
|
|
11
|
-
address: Address;
|
|
12
|
-
pubKey: string;
|
|
13
|
-
};
|
|
14
|
-
export const generateAccountFromPrivateKey = (privKey: string): Account => {
|
|
15
|
-
const pubKey = hd.key.privateToPublic(privKey);
|
|
16
|
-
const args = hd.key.publicKeyToBlake160(pubKey);
|
|
17
|
-
const template = lumosConfig.SCRIPTS['SECP256K1_BLAKE160']!;
|
|
18
|
-
const lockScript = {
|
|
19
|
-
codeHash: template.CODE_HASH,
|
|
20
|
-
hashType: template.HASH_TYPE,
|
|
21
|
-
args: args,
|
|
22
|
-
};
|
|
23
|
-
const address = helpers.encodeToAddress(lockScript, { config: lumosConfig });
|
|
24
|
-
return {
|
|
25
|
-
lockScript,
|
|
26
|
-
address,
|
|
27
|
-
pubKey,
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export async function capacityOf(address: string): Promise<BI> {
|
|
32
|
-
const collector = indexer.collector({
|
|
33
|
-
lock: helpers.parseAddress(address, { config: lumosConfig }),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
let balance = BI.from(0);
|
|
37
|
-
for await (const cell of collector.collect()) {
|
|
38
|
-
balance = balance.add(cell.cellOutput.capacity);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return balance;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface Options {
|
|
45
|
-
from: string;
|
|
46
|
-
to: string;
|
|
47
|
-
amount: string;
|
|
48
|
-
privKey: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function transfer(options: Options): Promise<string> {
|
|
52
|
-
let txSkeleton = helpers.TransactionSkeleton({});
|
|
53
|
-
const fromScript = helpers.parseAddress(options.from, {
|
|
54
|
-
config: lumosConfig,
|
|
55
|
-
});
|
|
56
|
-
const toScript = helpers.parseAddress(options.to, { config: lumosConfig });
|
|
57
|
-
|
|
58
|
-
if (BI.from(options.amount).lt(BI.from('6100000000'))) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
`every cell's capacity must be at least 61 CKB, see https://medium.com/nervosnetwork/understanding-the-nervos-dao-and-cell-model-d68f38272c24`,
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// additional 0.001 ckb for tx fee
|
|
65
|
-
// the tx fee could calculated by tx size
|
|
66
|
-
// this is just a simple example
|
|
67
|
-
const neededCapacity = BI.from(options.amount).add(100000);
|
|
68
|
-
let collectedSum = BI.from(0);
|
|
69
|
-
const collected: Cell[] = [];
|
|
70
|
-
const collector = indexer.collector({ lock: fromScript, type: 'empty' });
|
|
71
|
-
for await (const cell of collector.collect()) {
|
|
72
|
-
collectedSum = collectedSum.add(cell.cellOutput.capacity);
|
|
73
|
-
collected.push(cell);
|
|
74
|
-
if (collectedSum >= neededCapacity) break;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (collectedSum.lt(neededCapacity)) {
|
|
78
|
-
throw new Error(`Not enough CKB, ${collectedSum} < ${neededCapacity}`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const transferOutput: Cell = {
|
|
82
|
-
cellOutput: {
|
|
83
|
-
capacity: BI.from(options.amount).toHexString(),
|
|
84
|
-
lock: toScript,
|
|
85
|
-
},
|
|
86
|
-
data: '0x',
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const changeOutput: Cell = {
|
|
90
|
-
cellOutput: {
|
|
91
|
-
capacity: collectedSum.sub(neededCapacity).toHexString(),
|
|
92
|
-
lock: fromScript,
|
|
93
|
-
},
|
|
94
|
-
data: '0x',
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
txSkeleton = txSkeleton.update('inputs', (inputs) => inputs.push(...collected));
|
|
98
|
-
txSkeleton = txSkeleton.update('outputs', (outputs) => outputs.push(transferOutput, changeOutput));
|
|
99
|
-
txSkeleton = txSkeleton.update('cellDeps', (cellDeps) =>
|
|
100
|
-
cellDeps.push({
|
|
101
|
-
outPoint: {
|
|
102
|
-
txHash: lumosConfig.SCRIPTS.SECP256K1_BLAKE160.TX_HASH,
|
|
103
|
-
index: lumosConfig.SCRIPTS.SECP256K1_BLAKE160.INDEX,
|
|
104
|
-
},
|
|
105
|
-
depType: lumosConfig.SCRIPTS.SECP256K1_BLAKE160.DEP_TYPE,
|
|
106
|
-
}),
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const firstIndex = txSkeleton
|
|
110
|
-
.get('inputs')
|
|
111
|
-
.findIndex((input) =>
|
|
112
|
-
new ScriptValue(input.cellOutput.lock, { validate: false }).equals(
|
|
113
|
-
new ScriptValue(fromScript, { validate: false }),
|
|
114
|
-
),
|
|
115
|
-
);
|
|
116
|
-
if (firstIndex !== -1) {
|
|
117
|
-
while (firstIndex >= txSkeleton.get('witnesses').size) {
|
|
118
|
-
txSkeleton = txSkeleton.update('witnesses', (witnesses) => witnesses.push('0x'));
|
|
119
|
-
}
|
|
120
|
-
let witness: string = txSkeleton.get('witnesses').get(firstIndex)!;
|
|
121
|
-
const newWitnessArgs: WitnessArgs = {
|
|
122
|
-
/* 65-byte zeros in hex */
|
|
123
|
-
lock: '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
|
124
|
-
};
|
|
125
|
-
if (witness !== '0x') {
|
|
126
|
-
const witnessArgs = blockchain.WitnessArgs.unpack(bytes.bytify(witness));
|
|
127
|
-
const lock = witnessArgs.lock;
|
|
128
|
-
if (!!lock && !!newWitnessArgs.lock && !bytes.equal(lock, newWitnessArgs.lock)) {
|
|
129
|
-
throw new Error('Lock field in first witness is set aside for signature!');
|
|
130
|
-
}
|
|
131
|
-
const inputType = witnessArgs.inputType;
|
|
132
|
-
if (inputType) {
|
|
133
|
-
newWitnessArgs.inputType = inputType;
|
|
134
|
-
}
|
|
135
|
-
const outputType = witnessArgs.outputType;
|
|
136
|
-
if (outputType) {
|
|
137
|
-
newWitnessArgs.outputType = outputType;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
witness = bytes.hexify(blockchain.WitnessArgs.pack(newWitnessArgs));
|
|
141
|
-
txSkeleton = txSkeleton.update('witnesses', (witnesses) => witnesses.set(firstIndex, witness));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
txSkeleton = commons.common.prepareSigningEntries(txSkeleton);
|
|
145
|
-
const message = txSkeleton.get('signingEntries').get(0)?.message;
|
|
146
|
-
const Sig = hd.key.signRecoverable(message!, options.privKey);
|
|
147
|
-
const tx = helpers.sealTransaction(txSkeleton, [Sig]);
|
|
148
|
-
const hash = await rpc.sendTransaction(tx, 'passthrough');
|
|
149
|
-
console.log('The transaction hash is', hash);
|
|
150
|
-
alert(`The transaction hash is ${hash}`);
|
|
151
|
-
|
|
152
|
-
return hash;
|
|
153
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@offckb/lumos-scaffold",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"start": "parcel index.html",
|
|
8
|
-
"lint": "tsc --noEmit"
|
|
9
|
-
},
|
|
10
|
-
"keywords": [],
|
|
11
|
-
"author": "",
|
|
12
|
-
"license": "MIT",
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"@ckb-lumos/base": "0.21.1",
|
|
15
|
-
"@ckb-lumos/codec": "0.21.1",
|
|
16
|
-
"@ckb-lumos/lumos": "0.21.1",
|
|
17
|
-
"@types/react": "^18.0.25",
|
|
18
|
-
"@types/react-dom": "^18.0.9",
|
|
19
|
-
"react": "^18.2.0",
|
|
20
|
-
"react-dom": "^18.2.0"
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"crypto-browserify": "^3.12.0",
|
|
24
|
-
"parcel": "^2.9.3",
|
|
25
|
-
"path-browserify": "^1.0.0",
|
|
26
|
-
"process": "^0.11.10",
|
|
27
|
-
"stream-browserify": "^3.0.0"
|
|
28
|
-
}
|
|
29
|
-
}
|