@ckb-ccc/spore 0.1.0-alpha.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/CHANGELOG.md +12 -0
- package/README.md +61 -0
- package/dist/advanced.d.ts +5 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +4 -0
- package/dist/cluster/index.d.ts +56 -0
- package/dist/cluster/index.d.ts.map +1 -0
- package/dist/cluster/index.js +96 -0
- package/dist/cobuild/index.d.ts +13 -0
- package/dist/cobuild/index.d.ts.map +1 -0
- package/dist/cobuild/index.js +168 -0
- package/dist/codec/base.d.ts +6 -0
- package/dist/codec/base.d.ts.map +1 -0
- package/dist/codec/base.js +10 -0
- package/dist/codec/cluster.d.ts +41 -0
- package/dist/codec/cluster.d.ts.map +1 -0
- package/dist/codec/cluster.js +73 -0
- package/dist/codec/cobuild/buildingPacket.d.ts +465 -0
- package/dist/codec/cobuild/buildingPacket.d.ts.map +1 -0
- package/dist/codec/cobuild/buildingPacket.js +44 -0
- package/dist/codec/cobuild/index.d.ts +4 -0
- package/dist/codec/cobuild/index.d.ts.map +1 -0
- package/dist/codec/cobuild/index.js +3 -0
- package/dist/codec/cobuild/sporeAction.d.ts +314 -0
- package/dist/codec/cobuild/sporeAction.d.ts.map +1 -0
- package/dist/codec/cobuild/sporeAction.js +104 -0
- package/dist/codec/cobuild/witnessLayout.d.ts +43 -0
- package/dist/codec/cobuild/witnessLayout.d.ts.map +1 -0
- package/dist/codec/cobuild/witnessLayout.js +27 -0
- package/dist/codec/index.d.ts +4 -0
- package/dist/codec/index.d.ts.map +1 -0
- package/dist/codec/index.js +3 -0
- package/dist/codec/spore.d.ts +15 -0
- package/dist/codec/spore.d.ts.map +1 -0
- package/dist/codec/spore.js +24 -0
- package/dist/dob/api/decode.d.ts +6 -0
- package/dist/dob/api/decode.d.ts.map +1 -0
- package/dist/dob/api/decode.js +44 -0
- package/dist/dob/api/encode.d.ts +5 -0
- package/dist/dob/api/encode.d.ts.map +1 -0
- package/dist/dob/api/encode.js +77 -0
- package/dist/dob/api/index.d.ts +3 -0
- package/dist/dob/api/index.d.ts.map +1 -0
- package/dist/dob/api/index.js +2 -0
- package/dist/dob/config/index.d.ts +2 -0
- package/dist/dob/config/index.d.ts.map +1 -0
- package/dist/dob/config/index.js +1 -0
- package/dist/dob/config/predefined.d.ts +8 -0
- package/dist/dob/config/predefined.d.ts.map +1 -0
- package/dist/dob/config/predefined.js +59 -0
- package/dist/dob/helper/check.d.ts +5 -0
- package/dist/dob/helper/check.d.ts.map +1 -0
- package/dist/dob/helper/check.js +75 -0
- package/dist/dob/helper/error.d.ts +2 -0
- package/dist/dob/helper/error.d.ts.map +1 -0
- package/dist/dob/helper/error.js +40 -0
- package/dist/dob/helper/index.d.ts +3 -0
- package/dist/dob/helper/index.d.ts.map +1 -0
- package/dist/dob/helper/index.js +2 -0
- package/dist/dob/helper/object.d.ts +59 -0
- package/dist/dob/helper/object.d.ts.map +1 -0
- package/dist/dob/helper/object.js +1 -0
- package/dist/dob/index.d.ts +4 -0
- package/dist/dob/index.d.ts.map +1 -0
- package/dist/dob/index.js +3 -0
- package/dist/helper/index.d.ts +9 -0
- package/dist/helper/index.d.ts.map +1 -0
- package/dist/helper/index.js +37 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/package.json +3 -0
- package/dist/predefined/advanced.d.ts +3 -0
- package/dist/predefined/advanced.d.ts.map +1 -0
- package/dist/predefined/advanced.js +2 -0
- package/dist/predefined/index.d.ts +3 -0
- package/dist/predefined/index.d.ts.map +1 -0
- package/dist/predefined/index.js +2 -0
- package/dist/predefined/mainnet.advanced.d.ts +4 -0
- package/dist/predefined/mainnet.advanced.d.ts.map +1 -0
- package/dist/predefined/mainnet.advanced.js +61 -0
- package/dist/predefined/testnet.advanced.d.ts +4 -0
- package/dist/predefined/testnet.advanced.d.ts.map +1 -0
- package/dist/predefined/testnet.advanced.js +88 -0
- package/dist/predefined/types.d.ts +17 -0
- package/dist/predefined/types.d.ts.map +1 -0
- package/dist/predefined/types.js +18 -0
- package/dist/predefined/utils.d.ts +7 -0
- package/dist/predefined/utils.d.ts.map +1 -0
- package/dist/predefined/utils.js +26 -0
- package/dist/spore/advanced.d.ts +5 -0
- package/dist/spore/advanced.d.ts.map +1 -0
- package/dist/spore/advanced.js +62 -0
- package/dist/spore/index.d.ts +80 -0
- package/dist/spore/index.d.ts.map +1 -0
- package/dist/spore/index.js +135 -0
- package/dist.commonjs/advanced.d.ts +5 -0
- package/dist.commonjs/advanced.d.ts.map +1 -0
- package/dist.commonjs/advanced.js +20 -0
- package/dist.commonjs/cluster/index.d.ts +56 -0
- package/dist.commonjs/cluster/index.d.ts.map +1 -0
- package/dist.commonjs/cluster/index.js +102 -0
- package/dist.commonjs/cobuild/index.d.ts +13 -0
- package/dist.commonjs/cobuild/index.d.ts.map +1 -0
- package/dist.commonjs/cobuild/index.js +179 -0
- package/dist.commonjs/codec/base.d.ts +6 -0
- package/dist.commonjs/codec/base.d.ts.map +1 -0
- package/dist.commonjs/codec/base.js +13 -0
- package/dist.commonjs/codec/cluster.d.ts +41 -0
- package/dist.commonjs/codec/cluster.d.ts.map +1 -0
- package/dist.commonjs/codec/cluster.js +82 -0
- package/dist.commonjs/codec/cobuild/buildingPacket.d.ts +465 -0
- package/dist.commonjs/codec/cobuild/buildingPacket.d.ts.map +1 -0
- package/dist.commonjs/codec/cobuild/buildingPacket.js +47 -0
- package/dist.commonjs/codec/cobuild/index.d.ts +4 -0
- package/dist.commonjs/codec/cobuild/index.d.ts.map +1 -0
- package/dist.commonjs/codec/cobuild/index.js +19 -0
- package/dist.commonjs/codec/cobuild/sporeAction.d.ts +314 -0
- package/dist.commonjs/codec/cobuild/sporeAction.d.ts.map +1 -0
- package/dist.commonjs/codec/cobuild/sporeAction.js +107 -0
- package/dist.commonjs/codec/cobuild/witnessLayout.d.ts +43 -0
- package/dist.commonjs/codec/cobuild/witnessLayout.d.ts.map +1 -0
- package/dist.commonjs/codec/cobuild/witnessLayout.js +30 -0
- package/dist.commonjs/codec/index.d.ts +4 -0
- package/dist.commonjs/codec/index.d.ts.map +1 -0
- package/dist.commonjs/codec/index.js +19 -0
- package/dist.commonjs/codec/spore.d.ts +15 -0
- package/dist.commonjs/codec/spore.d.ts.map +1 -0
- package/dist.commonjs/codec/spore.js +29 -0
- package/dist.commonjs/dob/api/decode.d.ts +6 -0
- package/dist.commonjs/dob/api/decode.d.ts.map +1 -0
- package/dist.commonjs/dob/api/decode.js +49 -0
- package/dist.commonjs/dob/api/encode.d.ts +5 -0
- package/dist.commonjs/dob/api/encode.d.ts.map +1 -0
- package/dist.commonjs/dob/api/encode.js +82 -0
- package/dist.commonjs/dob/api/index.d.ts +3 -0
- package/dist.commonjs/dob/api/index.d.ts.map +1 -0
- package/dist.commonjs/dob/api/index.js +18 -0
- package/dist.commonjs/dob/config/index.d.ts +2 -0
- package/dist.commonjs/dob/config/index.d.ts.map +1 -0
- package/dist.commonjs/dob/config/index.js +17 -0
- package/dist.commonjs/dob/config/predefined.d.ts +8 -0
- package/dist.commonjs/dob/config/predefined.d.ts.map +1 -0
- package/dist.commonjs/dob/config/predefined.js +63 -0
- package/dist.commonjs/dob/helper/check.d.ts +5 -0
- package/dist.commonjs/dob/helper/check.d.ts.map +1 -0
- package/dist.commonjs/dob/helper/check.js +80 -0
- package/dist.commonjs/dob/helper/error.d.ts +2 -0
- package/dist.commonjs/dob/helper/error.d.ts.map +1 -0
- package/dist.commonjs/dob/helper/error.js +43 -0
- package/dist.commonjs/dob/helper/index.d.ts +3 -0
- package/dist.commonjs/dob/helper/index.d.ts.map +1 -0
- package/dist.commonjs/dob/helper/index.js +18 -0
- package/dist.commonjs/dob/helper/object.d.ts +59 -0
- package/dist.commonjs/dob/helper/object.d.ts.map +1 -0
- package/dist.commonjs/dob/helper/object.js +2 -0
- package/dist.commonjs/dob/index.d.ts +4 -0
- package/dist.commonjs/dob/index.d.ts.map +1 -0
- package/dist.commonjs/dob/index.js +19 -0
- package/dist.commonjs/helper/index.d.ts +9 -0
- package/dist.commonjs/helper/index.d.ts.map +1 -0
- package/dist.commonjs/helper/index.js +42 -0
- package/dist.commonjs/index.d.ts +5 -0
- package/dist.commonjs/index.d.ts.map +1 -0
- package/dist.commonjs/index.js +33 -0
- package/dist.commonjs/package.json +3 -0
- package/dist.commonjs/predefined/advanced.d.ts +3 -0
- package/dist.commonjs/predefined/advanced.d.ts.map +1 -0
- package/dist.commonjs/predefined/advanced.js +18 -0
- package/dist.commonjs/predefined/index.d.ts +3 -0
- package/dist.commonjs/predefined/index.d.ts.map +1 -0
- package/dist.commonjs/predefined/index.js +18 -0
- package/dist.commonjs/predefined/mainnet.advanced.d.ts +4 -0
- package/dist.commonjs/predefined/mainnet.advanced.d.ts.map +1 -0
- package/dist.commonjs/predefined/mainnet.advanced.js +64 -0
- package/dist.commonjs/predefined/testnet.advanced.d.ts +4 -0
- package/dist.commonjs/predefined/testnet.advanced.d.ts.map +1 -0
- package/dist.commonjs/predefined/testnet.advanced.js +91 -0
- package/dist.commonjs/predefined/types.d.ts +17 -0
- package/dist.commonjs/predefined/types.d.ts.map +1 -0
- package/dist.commonjs/predefined/types.js +22 -0
- package/dist.commonjs/predefined/utils.d.ts +7 -0
- package/dist.commonjs/predefined/utils.d.ts.map +1 -0
- package/dist.commonjs/predefined/utils.js +32 -0
- package/dist.commonjs/spore/advanced.d.ts +5 -0
- package/dist.commonjs/spore/advanced.d.ts.map +1 -0
- package/dist.commonjs/spore/advanced.js +65 -0
- package/dist.commonjs/spore/index.d.ts +80 -0
- package/dist.commonjs/spore/index.d.ts.map +1 -0
- package/dist.commonjs/spore/index.js +142 -0
- package/package.json +52 -0
- package/src/advanced.ts +4 -0
- package/src/cluster/index.ts +180 -0
- package/src/cobuild/index.ts +220 -0
- package/src/codec/base.ts +11 -0
- package/src/codec/cluster.ts +133 -0
- package/src/codec/cobuild/buildingPacket.ts +72 -0
- package/src/codec/cobuild/index.ts +3 -0
- package/src/codec/cobuild/sporeAction.ts +153 -0
- package/src/codec/cobuild/witnessLayout.ts +40 -0
- package/src/codec/index.ts +3 -0
- package/src/codec/spore.ts +36 -0
- package/src/dob/api/decode.ts +61 -0
- package/src/dob/api/encode.ts +84 -0
- package/src/dob/api/index.ts +2 -0
- package/src/dob/config/index.ts +1 -0
- package/src/dob/config/predefined.ts +71 -0
- package/src/dob/helper/check.ts +107 -0
- package/src/dob/helper/error.ts +41 -0
- package/src/dob/helper/index.ts +2 -0
- package/src/dob/helper/object.ts +66 -0
- package/src/dob/index.ts +3 -0
- package/src/helper/index.ts +68 -0
- package/src/index.ts +4 -0
- package/src/predefined/advanced.ts +2 -0
- package/src/predefined/index.ts +2 -0
- package/src/predefined/mainnet.advanced.ts +76 -0
- package/src/predefined/testnet.advanced.ts +107 -0
- package/src/predefined/types.ts +37 -0
- package/src/predefined/utils.ts +56 -0
- package/src/spore/advanced.ts +88 -0
- package/src/spore/index.ts +236 -0
- package/typedoc.json +6 -0
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ckb-ccc/spore",
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
|
+
"description": "CCC - CKBer's Codebase. Common Chains Connector's support for Spore protocol",
|
|
5
|
+
"author": "ashuralyk <ashuralyk@live.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"private": false,
|
|
8
|
+
"homepage": "https://github.com/ckb-ecofund/ccc",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git://github.com/ckb-ecofund/ccc.git"
|
|
12
|
+
},
|
|
13
|
+
"main": "dist.commonjs/index.js",
|
|
14
|
+
"module": "dist/index.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"default": "./dist.commonjs/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./advanced": {
|
|
21
|
+
"import": "./dist/advanced.js",
|
|
22
|
+
"default": "./dist.commonjs/advanced.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@eslint/js": "^9.1.1",
|
|
27
|
+
"copyfiles": "^2.4.1",
|
|
28
|
+
"eslint": "^9.1.0",
|
|
29
|
+
"eslint-config-prettier": "^9.1.0",
|
|
30
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
31
|
+
"prettier": "^3.2.5",
|
|
32
|
+
"prettier-plugin-organize-imports": "^3.2.4",
|
|
33
|
+
"rimraf": "^5.0.5",
|
|
34
|
+
"typescript": "^5.4.5",
|
|
35
|
+
"typescript-eslint": "^7.7.0",
|
|
36
|
+
"dotenv": "^16.4.5"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@ckb-lumos/base": "^0.24.0-next.1",
|
|
43
|
+
"@ckb-lumos/codec": "^0.24.0-next.1",
|
|
44
|
+
"axios": "^1.7.7",
|
|
45
|
+
"@ckb-ccc/core": "0.1.0-alpha.4"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "rimraf ./dist && rimraf ./dist.commonjs && tsc && tsc --project tsconfig.commonjs.json && copyfiles -u 2 misc/basedirs/**/* .",
|
|
49
|
+
"lint": "eslint ./src",
|
|
50
|
+
"format": "prettier --write . && eslint --fix ./src"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/advanced.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { ccc } from "@ckb-ccc/core";
|
|
2
|
+
import {
|
|
3
|
+
assembleCreateClusterAction,
|
|
4
|
+
assembleTransferClusterAction,
|
|
5
|
+
prepareSporeTransaction,
|
|
6
|
+
} from "../advanced.js";
|
|
7
|
+
import { ClusterData, packRawClusterData } from "../codec/index.js";
|
|
8
|
+
import {
|
|
9
|
+
findSingletonCellByArgs,
|
|
10
|
+
injectOneCapacityCell,
|
|
11
|
+
} from "../helper/index.js";
|
|
12
|
+
import {
|
|
13
|
+
SporeScriptInfo,
|
|
14
|
+
SporeScriptInfoLike,
|
|
15
|
+
getClusterScriptInfo,
|
|
16
|
+
getClusterScriptInfos,
|
|
17
|
+
} from "../predefined/index.js";
|
|
18
|
+
|
|
19
|
+
export async function findCluster(
|
|
20
|
+
client: ccc.Client,
|
|
21
|
+
args: ccc.HexLike,
|
|
22
|
+
scripts?: SporeScriptInfoLike[],
|
|
23
|
+
): Promise<
|
|
24
|
+
| {
|
|
25
|
+
cell: ccc.Cell;
|
|
26
|
+
scriptInfo: SporeScriptInfo;
|
|
27
|
+
}
|
|
28
|
+
| undefined
|
|
29
|
+
> {
|
|
30
|
+
return findSingletonCellByArgs(
|
|
31
|
+
client,
|
|
32
|
+
args,
|
|
33
|
+
scripts ?? Object.values(getClusterScriptInfos(client)),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function assertCluster(
|
|
38
|
+
client: ccc.Client,
|
|
39
|
+
args: ccc.HexLike,
|
|
40
|
+
scripts?: SporeScriptInfoLike[],
|
|
41
|
+
): Promise<{
|
|
42
|
+
cell: ccc.Cell;
|
|
43
|
+
scriptInfo: SporeScriptInfo;
|
|
44
|
+
}> {
|
|
45
|
+
const res = await findCluster(client, args, scripts);
|
|
46
|
+
|
|
47
|
+
if (!res) {
|
|
48
|
+
throw new Error(`Cluster ${ccc.hexFrom(args)} not found`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return res;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create a new Cluster cell
|
|
56
|
+
*
|
|
57
|
+
* @param signer who takes the responsibility to balance and sign the transaction
|
|
58
|
+
* @param data specific format of data required by Cluster protocol
|
|
59
|
+
* @param to the owner of the Cluster cell, which will be replaced with signer if not provided
|
|
60
|
+
* @param tx the transaction skeleton, if not provided, a new one will be created
|
|
61
|
+
* @param scriptInfo the script info of new cluster, default spore version if undefined
|
|
62
|
+
* @param scriptInfoHash the script info hash used in cobuild
|
|
63
|
+
* @returns
|
|
64
|
+
* - **tx**: a new transaction that contains created Cluster cell
|
|
65
|
+
* - **id**: the id of the created Cluster cell
|
|
66
|
+
*/
|
|
67
|
+
export async function createSporeCluster(params: {
|
|
68
|
+
signer: ccc.Signer;
|
|
69
|
+
data: ClusterData;
|
|
70
|
+
to?: ccc.ScriptLike;
|
|
71
|
+
tx?: ccc.TransactionLike;
|
|
72
|
+
scriptInfo?: SporeScriptInfoLike;
|
|
73
|
+
scriptInfoHash?: ccc.HexLike;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
tx: ccc.Transaction;
|
|
76
|
+
id: ccc.Hex;
|
|
77
|
+
}> {
|
|
78
|
+
const { signer, data, to, scriptInfoHash } = params;
|
|
79
|
+
const scriptInfo = params.scriptInfo ?? getClusterScriptInfo(signer.client);
|
|
80
|
+
|
|
81
|
+
// prepare transaction
|
|
82
|
+
const tx = ccc.Transaction.from(params.tx ?? {});
|
|
83
|
+
if (tx.inputs.length === 0) {
|
|
84
|
+
await injectOneCapacityCell(signer, tx);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// build cluster cell
|
|
88
|
+
const id = ccc.hashTypeId(tx.inputs[0], tx.outputs.length);
|
|
89
|
+
const packedClusterData = packRawClusterData(data);
|
|
90
|
+
tx.addOutput(
|
|
91
|
+
{
|
|
92
|
+
lock: to ?? (await signer.getRecommendedAddressObj()).script,
|
|
93
|
+
type: {
|
|
94
|
+
...scriptInfo,
|
|
95
|
+
args: id,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
packedClusterData,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// complete cellDeps
|
|
102
|
+
await tx.addCellDepInfos(signer.client, scriptInfo.cellDeps);
|
|
103
|
+
|
|
104
|
+
// generate cobuild action
|
|
105
|
+
const actions = scriptInfo.cobuild
|
|
106
|
+
? [
|
|
107
|
+
assembleCreateClusterAction(
|
|
108
|
+
tx.outputs[tx.outputs.length - 1],
|
|
109
|
+
packedClusterData,
|
|
110
|
+
scriptInfoHash,
|
|
111
|
+
),
|
|
112
|
+
]
|
|
113
|
+
: [];
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
tx: await prepareSporeTransaction(signer, tx, actions),
|
|
117
|
+
id,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Transfer a Cluster cell
|
|
123
|
+
*
|
|
124
|
+
* @param signer who takes the responsibility to balance and sign the transaction
|
|
125
|
+
* @param id the id of the Cluster cell to be transferred
|
|
126
|
+
* @param to the new owner of the Cluster cell
|
|
127
|
+
* @param tx the transaction skeleton, if not provided, a new one will be created
|
|
128
|
+
* @param scriptInfoHash the script info hash used in cobuild
|
|
129
|
+
* @returns
|
|
130
|
+
* - **tx**: a new transaction that contains transferred Cluster cell
|
|
131
|
+
*/
|
|
132
|
+
export async function transferSporeCluster(params: {
|
|
133
|
+
signer: ccc.Signer;
|
|
134
|
+
id: ccc.HexLike;
|
|
135
|
+
to: ccc.ScriptLike;
|
|
136
|
+
tx?: ccc.TransactionLike;
|
|
137
|
+
scriptInfoHash?: ccc.HexLike;
|
|
138
|
+
}): Promise<{
|
|
139
|
+
tx: ccc.Transaction;
|
|
140
|
+
}> {
|
|
141
|
+
const { signer, id, to, scriptInfoHash } = params;
|
|
142
|
+
|
|
143
|
+
// prepare transaction
|
|
144
|
+
const tx = ccc.Transaction.from(params.tx ?? {});
|
|
145
|
+
|
|
146
|
+
// build cluster cell
|
|
147
|
+
const { cell: cluster, scriptInfo } = await assertCluster(signer.client, id);
|
|
148
|
+
|
|
149
|
+
tx.inputs.push(
|
|
150
|
+
ccc.CellInput.from({
|
|
151
|
+
previousOutput: cluster.outPoint,
|
|
152
|
+
...cluster,
|
|
153
|
+
}),
|
|
154
|
+
);
|
|
155
|
+
tx.addOutput(
|
|
156
|
+
{
|
|
157
|
+
lock: to,
|
|
158
|
+
type: cluster.cellOutput.type,
|
|
159
|
+
},
|
|
160
|
+
cluster.outputData,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// complete cellDeps
|
|
164
|
+
await tx.addCellDepInfos(signer.client, scriptInfo.cellDeps);
|
|
165
|
+
|
|
166
|
+
// generate cobuild action
|
|
167
|
+
const actions = scriptInfo.cobuild
|
|
168
|
+
? [
|
|
169
|
+
assembleTransferClusterAction(
|
|
170
|
+
cluster.cellOutput,
|
|
171
|
+
tx.outputs[tx.outputs.length - 1],
|
|
172
|
+
scriptInfoHash,
|
|
173
|
+
),
|
|
174
|
+
]
|
|
175
|
+
: [];
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
tx: await prepareSporeTransaction(signer, tx, actions),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { ccc } from "@ckb-ccc/core";
|
|
2
|
+
import { UnpackResult } from "@ckb-lumos/codec";
|
|
3
|
+
import {
|
|
4
|
+
Action,
|
|
5
|
+
ActionVec,
|
|
6
|
+
SporeAction,
|
|
7
|
+
WitnessLayout,
|
|
8
|
+
} from "../codec/index.js";
|
|
9
|
+
import { DEFAULT_COBUILD_INFO_HASH } from "../predefined/index.js";
|
|
10
|
+
|
|
11
|
+
export function assembleCreateSporeAction(
|
|
12
|
+
sporeOutput: ccc.CellOutputLike,
|
|
13
|
+
sporeData: ccc.BytesLike,
|
|
14
|
+
scriptInfoHash: ccc.HexLike = DEFAULT_COBUILD_INFO_HASH,
|
|
15
|
+
): UnpackResult<typeof Action> {
|
|
16
|
+
if (!sporeOutput.type) {
|
|
17
|
+
throw new Error("Spore cell must have a type script");
|
|
18
|
+
}
|
|
19
|
+
const sporeType = ccc.Script.from(sporeOutput.type);
|
|
20
|
+
const sporeTypeHash = sporeType.hash();
|
|
21
|
+
const actionData = SporeAction.pack({
|
|
22
|
+
type: "CreateSpore",
|
|
23
|
+
value: {
|
|
24
|
+
sporeId: sporeType.args,
|
|
25
|
+
dataHash: ccc.hashCkb(sporeData),
|
|
26
|
+
to: {
|
|
27
|
+
type: "Script",
|
|
28
|
+
value: ccc.Script.from(sporeOutput.lock),
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
scriptInfoHash: ccc.hexFrom(scriptInfoHash),
|
|
34
|
+
scriptHash: sporeTypeHash,
|
|
35
|
+
data: ccc.hexFrom(actionData),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function assembleTransferSporeAction(
|
|
40
|
+
sporeInput: ccc.CellOutputLike,
|
|
41
|
+
sporeOutput: ccc.CellOutputLike,
|
|
42
|
+
scriptInfoHash: ccc.HexLike = DEFAULT_COBUILD_INFO_HASH,
|
|
43
|
+
): UnpackResult<typeof Action> {
|
|
44
|
+
if (!sporeInput.type || !sporeOutput.type) {
|
|
45
|
+
throw new Error("Spore cell must have a type script");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const sporeType = ccc.Script.from(sporeOutput.type);
|
|
49
|
+
const sporeTypeHash = sporeType.hash();
|
|
50
|
+
const actionData = SporeAction.pack({
|
|
51
|
+
type: "TransferSpore",
|
|
52
|
+
value: {
|
|
53
|
+
sporeId: sporeType.args,
|
|
54
|
+
from: {
|
|
55
|
+
type: "Script",
|
|
56
|
+
value: ccc.Script.from(sporeInput.lock),
|
|
57
|
+
},
|
|
58
|
+
to: {
|
|
59
|
+
type: "Script",
|
|
60
|
+
value: ccc.Script.from(sporeOutput.lock),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
scriptInfoHash: ccc.hexFrom(scriptInfoHash),
|
|
66
|
+
scriptHash: sporeTypeHash,
|
|
67
|
+
data: ccc.hexFrom(actionData),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function assembleMeltSporeAction(
|
|
72
|
+
sporeInput: ccc.CellOutputLike,
|
|
73
|
+
scriptInfoHash: ccc.HexLike = DEFAULT_COBUILD_INFO_HASH,
|
|
74
|
+
): UnpackResult<typeof Action> {
|
|
75
|
+
if (!sporeInput.type) {
|
|
76
|
+
throw new Error("Spore cell must have a type script");
|
|
77
|
+
}
|
|
78
|
+
const sporeType = ccc.Script.from(sporeInput.type);
|
|
79
|
+
const sporeTypeHash = sporeType.hash();
|
|
80
|
+
const actionData = SporeAction.pack({
|
|
81
|
+
type: "MeltSpore",
|
|
82
|
+
value: {
|
|
83
|
+
sporeId: sporeType.args,
|
|
84
|
+
from: {
|
|
85
|
+
type: "Script",
|
|
86
|
+
value: ccc.Script.from(sporeInput.lock),
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
scriptInfoHash: ccc.hexFrom(scriptInfoHash),
|
|
92
|
+
scriptHash: sporeTypeHash,
|
|
93
|
+
data: ccc.hexFrom(actionData),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function assembleCreateClusterAction(
|
|
98
|
+
clusterOutput: ccc.CellOutputLike,
|
|
99
|
+
clusterData: ccc.BytesLike,
|
|
100
|
+
scriptInfoHash: ccc.HexLike = DEFAULT_COBUILD_INFO_HASH,
|
|
101
|
+
): UnpackResult<typeof Action> {
|
|
102
|
+
if (!clusterOutput.type) {
|
|
103
|
+
throw new Error("Cluster cell must have a type script");
|
|
104
|
+
}
|
|
105
|
+
const clusterType = ccc.Script.from(clusterOutput.type);
|
|
106
|
+
const clusterTypeHash = clusterType.hash();
|
|
107
|
+
const actionData = SporeAction.pack({
|
|
108
|
+
type: "CreateCluster",
|
|
109
|
+
value: {
|
|
110
|
+
clusterId: clusterType.args,
|
|
111
|
+
dataHash: ccc.hashCkb(clusterData),
|
|
112
|
+
to: {
|
|
113
|
+
type: "Script",
|
|
114
|
+
value: ccc.Script.from(clusterOutput.lock),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
scriptInfoHash: ccc.hexFrom(scriptInfoHash),
|
|
120
|
+
scriptHash: clusterTypeHash,
|
|
121
|
+
data: ccc.hexFrom(actionData),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function assembleTransferClusterAction(
|
|
126
|
+
clusterInput: ccc.CellOutputLike,
|
|
127
|
+
clusterOutput: ccc.CellOutputLike,
|
|
128
|
+
scriptInfoHash: ccc.HexLike = DEFAULT_COBUILD_INFO_HASH,
|
|
129
|
+
): UnpackResult<typeof Action> {
|
|
130
|
+
if (!clusterInput.type || !clusterOutput.type) {
|
|
131
|
+
throw new Error("Cluster cell must have a type script");
|
|
132
|
+
}
|
|
133
|
+
const clusterType = ccc.Script.from(clusterOutput.type);
|
|
134
|
+
const clusterTypeHash = clusterType.hash();
|
|
135
|
+
const actionData = SporeAction.pack({
|
|
136
|
+
type: "TransferCluster",
|
|
137
|
+
value: {
|
|
138
|
+
clusterId: clusterType.args,
|
|
139
|
+
from: {
|
|
140
|
+
type: "Script",
|
|
141
|
+
value: ccc.Script.from(clusterInput.lock),
|
|
142
|
+
},
|
|
143
|
+
to: {
|
|
144
|
+
type: "Script",
|
|
145
|
+
value: ccc.Script.from(clusterOutput.lock),
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
scriptInfoHash: ccc.hexFrom(scriptInfoHash),
|
|
151
|
+
scriptHash: clusterTypeHash,
|
|
152
|
+
data: ccc.hexFrom(actionData),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export async function prepareSporeTransaction(
|
|
157
|
+
signer: ccc.Signer,
|
|
158
|
+
txLike: ccc.TransactionLike,
|
|
159
|
+
actions: UnpackResult<typeof ActionVec>,
|
|
160
|
+
): Promise<ccc.Transaction> {
|
|
161
|
+
let tx = ccc.Transaction.from(txLike);
|
|
162
|
+
|
|
163
|
+
if (actions.length === 0) {
|
|
164
|
+
return signer.prepareTransaction(tx);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const existedActions = extractCobuildActionsFromTx(tx);
|
|
168
|
+
tx = await signer.prepareTransaction(tx);
|
|
169
|
+
injectCobuild(tx, [...existedActions, ...actions]);
|
|
170
|
+
return tx;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function unpackCommonCobuildProof(
|
|
174
|
+
data: ccc.HexLike,
|
|
175
|
+
): UnpackResult<typeof WitnessLayout> | undefined {
|
|
176
|
+
try {
|
|
177
|
+
return WitnessLayout.unpack(ccc.bytesFrom(data));
|
|
178
|
+
} catch {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function extractCobuildActionsFromTx(
|
|
184
|
+
tx: ccc.Transaction,
|
|
185
|
+
): UnpackResult<typeof ActionVec> {
|
|
186
|
+
if (tx.witnesses.length === 0) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
const witnessLayout = unpackCommonCobuildProof(
|
|
190
|
+
tx.witnesses[tx.witnesses.length - 1],
|
|
191
|
+
);
|
|
192
|
+
if (!witnessLayout) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
if (witnessLayout.type !== "SighashAll") {
|
|
196
|
+
throw new Error("Invalid cobuild proof type: " + witnessLayout.type);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Remove existed cobuild witness
|
|
200
|
+
tx.witnesses.pop();
|
|
201
|
+
return witnessLayout.value.message.actions;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function injectCobuild(
|
|
205
|
+
tx: ccc.Transaction,
|
|
206
|
+
actions: UnpackResult<typeof ActionVec>,
|
|
207
|
+
): void {
|
|
208
|
+
const witnessLayout = ccc.hexFrom(
|
|
209
|
+
WitnessLayout.pack({
|
|
210
|
+
type: "SighashAll",
|
|
211
|
+
value: {
|
|
212
|
+
seal: "0x",
|
|
213
|
+
message: {
|
|
214
|
+
actions,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
}),
|
|
218
|
+
);
|
|
219
|
+
tx.witnesses.push(ccc.hexFrom(witnessLayout));
|
|
220
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ccc } from "@ckb-ccc/core";
|
|
2
|
+
import { molecule } from "@ckb-lumos/codec";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The codec for packing/unpacking UTF-8 raw strings.
|
|
6
|
+
* Should be packed like so: String.pack('something')
|
|
7
|
+
*/
|
|
8
|
+
export const RawString = molecule.byteVecOf({
|
|
9
|
+
pack: (packable: string) => ccc.bytesFrom(packable, "utf8"),
|
|
10
|
+
unpack: (unpackable: ccc.BytesLike) => ccc.bytesTo(unpackable, "utf8"),
|
|
11
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { ccc } from "@ckb-ccc/core";
|
|
2
|
+
import { blockchain } from "@ckb-lumos/base";
|
|
3
|
+
import { molecule } from "@ckb-lumos/codec";
|
|
4
|
+
import { RawString } from "./base.js";
|
|
5
|
+
|
|
6
|
+
export const MolClusterDataV1 = molecule.table(
|
|
7
|
+
{
|
|
8
|
+
name: RawString,
|
|
9
|
+
description: RawString,
|
|
10
|
+
},
|
|
11
|
+
["name", "description"],
|
|
12
|
+
);
|
|
13
|
+
export const MolClusterDataV2 = molecule.table(
|
|
14
|
+
{
|
|
15
|
+
name: RawString,
|
|
16
|
+
description: RawString,
|
|
17
|
+
mutantId: blockchain.BytesOpt,
|
|
18
|
+
},
|
|
19
|
+
["name", "description", "mutantId"],
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export interface ClusterDataV1 {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ClusterDataV2 {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
mutantId?: ccc.HexLike;
|
|
30
|
+
}
|
|
31
|
+
export type ClusterData = ClusterDataV2;
|
|
32
|
+
|
|
33
|
+
export type ClusterDataVersion = "v1" | "v2";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Pack RawClusterData to Uint8Array.
|
|
37
|
+
* Pass an optional "version" field to select a specific packing version.
|
|
38
|
+
*/
|
|
39
|
+
export function packRawClusterData(packable: ClusterData): Uint8Array;
|
|
40
|
+
export function packRawClusterData(
|
|
41
|
+
packable: ClusterDataV1,
|
|
42
|
+
version: "v1",
|
|
43
|
+
): Uint8Array;
|
|
44
|
+
export function packRawClusterData(
|
|
45
|
+
packable: ClusterDataV2,
|
|
46
|
+
version: "v2",
|
|
47
|
+
): Uint8Array;
|
|
48
|
+
export function packRawClusterData(
|
|
49
|
+
packable: ClusterDataV1 | ClusterDataV2,
|
|
50
|
+
version?: ClusterDataVersion,
|
|
51
|
+
): Uint8Array {
|
|
52
|
+
if (!version) {
|
|
53
|
+
return packRawClusterDataV2(packable);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
switch (version) {
|
|
57
|
+
case "v1":
|
|
58
|
+
return packRawClusterDataV1(packable);
|
|
59
|
+
case "v2":
|
|
60
|
+
return packRawClusterDataV2(packable);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function packRawClusterDataV1(packable: ClusterDataV1): Uint8Array {
|
|
64
|
+
return MolClusterDataV1.pack({
|
|
65
|
+
name: packable.name,
|
|
66
|
+
description: packable.description,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function packRawClusterDataV2(packable: ClusterDataV2): Uint8Array {
|
|
70
|
+
return MolClusterDataV2.pack({
|
|
71
|
+
name: packable.name,
|
|
72
|
+
description: packable.description,
|
|
73
|
+
mutantId: packable.mutantId,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Unpack Hex/Bytes to RawClusterData.
|
|
79
|
+
* Pass an optional "version" field to select a specific unpacking version.
|
|
80
|
+
*/
|
|
81
|
+
export function unpackToRawClusterData(unpackable: ccc.BytesLike): ClusterData;
|
|
82
|
+
export function unpackToRawClusterData(
|
|
83
|
+
unpackable: ccc.BytesLike,
|
|
84
|
+
version: "v1",
|
|
85
|
+
): ClusterDataV1;
|
|
86
|
+
export function unpackToRawClusterData(
|
|
87
|
+
unpackable: ccc.BytesLike,
|
|
88
|
+
version: "v2",
|
|
89
|
+
): ClusterDataV2;
|
|
90
|
+
export function unpackToRawClusterData(
|
|
91
|
+
unpackable: ccc.BytesLike,
|
|
92
|
+
version?: ClusterDataVersion,
|
|
93
|
+
): unknown {
|
|
94
|
+
if (version) {
|
|
95
|
+
switch (version) {
|
|
96
|
+
case "v1":
|
|
97
|
+
return unpackToRawClusterDataV1(unpackable);
|
|
98
|
+
case "v2":
|
|
99
|
+
return unpackToRawClusterDataV2(unpackable);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
return unpackToRawClusterDataV2(unpackable);
|
|
105
|
+
} catch {
|
|
106
|
+
try {
|
|
107
|
+
return unpackToRawClusterDataV1(unpackable);
|
|
108
|
+
} catch {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Cannot unpack ClusterData, no matching molecule: ${ccc.hexFrom(unpackable)}`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export function unpackToRawClusterDataV1(
|
|
116
|
+
unpackable: ccc.BytesLike,
|
|
117
|
+
): ClusterDataV1 {
|
|
118
|
+
const decoded = MolClusterDataV1.unpack(unpackable);
|
|
119
|
+
return {
|
|
120
|
+
name: decoded.name,
|
|
121
|
+
description: decoded.description,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function unpackToRawClusterDataV2(
|
|
125
|
+
unpackable: ccc.BytesLike,
|
|
126
|
+
): ClusterDataV2 {
|
|
127
|
+
const decoded = MolClusterDataV2.unpack(unpackable);
|
|
128
|
+
return {
|
|
129
|
+
name: decoded.name,
|
|
130
|
+
description: decoded.description,
|
|
131
|
+
mutantId: ccc.apply(ccc.hexFrom, decoded.mutantId),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { blockchain } from "@ckb-lumos/base";
|
|
2
|
+
import { molecule, number } from "@ckb-lumos/codec";
|
|
3
|
+
import { RawString } from "../base.js";
|
|
4
|
+
|
|
5
|
+
const Uint32Opt = molecule.option(number.Uint32LE);
|
|
6
|
+
|
|
7
|
+
const Hash = blockchain.Byte32;
|
|
8
|
+
|
|
9
|
+
export const Action = molecule.table(
|
|
10
|
+
{
|
|
11
|
+
scriptInfoHash: Hash,
|
|
12
|
+
scriptHash: Hash,
|
|
13
|
+
data: blockchain.Bytes,
|
|
14
|
+
},
|
|
15
|
+
["scriptInfoHash", "scriptHash", "data"],
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export const ActionVec = molecule.vector(Action);
|
|
19
|
+
|
|
20
|
+
export const Message = molecule.table(
|
|
21
|
+
{
|
|
22
|
+
actions: ActionVec,
|
|
23
|
+
},
|
|
24
|
+
["actions"],
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export const ResolvedInputs = molecule.table(
|
|
28
|
+
{
|
|
29
|
+
outputs: blockchain.CellOutputVec,
|
|
30
|
+
outputsData: blockchain.BytesVec,
|
|
31
|
+
},
|
|
32
|
+
["outputs", "outputsData"],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export const ScriptInfo = molecule.table(
|
|
36
|
+
{
|
|
37
|
+
name: RawString,
|
|
38
|
+
url: RawString,
|
|
39
|
+
scriptHash: Hash,
|
|
40
|
+
schema: RawString,
|
|
41
|
+
messageType: RawString,
|
|
42
|
+
},
|
|
43
|
+
["name", "url", "scriptHash", "schema", "messageType"],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export const ScriptInfoVec = molecule.vector(ScriptInfo);
|
|
47
|
+
|
|
48
|
+
export const BuildingPacketV1 = molecule.table(
|
|
49
|
+
{
|
|
50
|
+
message: Message,
|
|
51
|
+
payload: blockchain.Transaction,
|
|
52
|
+
resolvedInputs: ResolvedInputs,
|
|
53
|
+
changeOutput: Uint32Opt,
|
|
54
|
+
scriptInfos: ScriptInfoVec,
|
|
55
|
+
lockActions: ActionVec,
|
|
56
|
+
},
|
|
57
|
+
[
|
|
58
|
+
"message",
|
|
59
|
+
"payload",
|
|
60
|
+
"resolvedInputs",
|
|
61
|
+
"changeOutput",
|
|
62
|
+
"scriptInfos",
|
|
63
|
+
"lockActions",
|
|
64
|
+
],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
export const BuildingPacket = molecule.union(
|
|
68
|
+
{
|
|
69
|
+
BuildingPacketV1,
|
|
70
|
+
},
|
|
71
|
+
["BuildingPacketV1"],
|
|
72
|
+
);
|