This file provides guidance for AI assistants (Claude, GPT, Copilot, etc.) to help users work with this CKB JavaScript smart contract template.
ckb-script-app is a boilerplate for building smart contracts on the CKB (Nervos Common Knowledge Base) blockchain using TypeScript/JavaScript. It uses ckb-js-vm - a JavaScript virtual machine that runs on CKB.
Unlike Ethereum where smart contracts are written in Solidity, CKB allows smart contracts in any language that compiles to RISC-V. The ckb-js-vm is a QuickJS-based JavaScript runtime compiled to RISC-V, enabling developers to write contracts in TypeScript/JavaScript.
ckb-script-app/
├── contracts/ # Smart contract source code (TypeScript)
│ └── <contract-name>/
│ └── src/
│ └── index.ts # Contract entry point
├── tests/ # Jest tests for contracts
│ ├── *.mock.test.ts # Mock tests (no network, uses ckb-testtool)
│ ├── *.devnet.test.ts # Devnet tests (requires local node)
│ └── helper.ts # Test utilities
├── scripts/ # Build tooling
│ ├── build-all.js # Build all contracts
│ ├── build-contract.js # Build single contract
│ ├── add-contract.js # Scaffold new contract
│ └── deploy.js # Deploy to CKB networks
├── dist/ # Build output (generated)
│ ├── <name>.js # Bundled JavaScript
│ └── <name>.bc # Compiled bytecode for CKB
├── deployment/ # Deployment artifacts
│ ├── scripts.json # Deployed contract info
│ └── system-scripts.json # CKB system scripts info
├── app/ # Next.js frontend (optional)
│ ├── app/ # App router pages
│ ├── components/ # React components
│ └── utils/ # CKB client utilities
├── .skills/ # AI skill patterns (Agent Skills format)
│ ├── ckb-contract-patterns/ # Contract writing patterns
│ └── ckb-ccc-frontend/ # Frontend integration patterns
└── Configuration files...
| Task | Command |
|---|---|
| Install dependencies | pnpm install |
| Build all contracts | pnpm run build |
| Build one contract | pnpm run build:contract <name> |
| Run all tests | pnpm test |
| Add new contract | pnpm run add-contract <name> |
| Deploy to devnet | pnpm run deploy |
| Deploy to testnet | pnpm run deploy -- --network testnet |
| Start frontend | cd app && pnpm dev |
Every contract must export a main() function that returns an exit code (0 = success):
import * as bindings from '@ckb-js-std/bindings';
import { Script, HighLevel, log } from '@ckb-js-std/core';
function main(): number {
log.setLevel(log.LogLevel.Debug);
// Load current script info
let script = bindings.loadScript();
log.debug(`Script loaded: ${JSON.stringify(script)}`);
// Your validation logic here
// Return 0 for success, non-zero for failure
return 0;
}
bindings.exit(main());loadScript()- Get current script infoloadCell(index, source)- Load cell dataloadCellData(index, source)- Load cell data fieldloadInput(index, source)- Load inputloadWitness(index, source)- Load witnessloadHeader(index, source)- Load headerexit(code)- Exit with code
SOURCE_INPUT(1) - Input cellsSOURCE_OUTPUT(2) - Output cellsSOURCE_CELL_DEP(3) - Cell dependenciesSOURCE_GROUP_INPUT(0x0100000001) - Input cells in same groupSOURCE_GROUP_OUTPUT(0x0100000002) - Output cells in same group
Uses ckb-testtool to simulate CKB environment without a real node:
import { Resource, Verifier, DEFAULT_SCRIPT_CKB_JS_VM } from 'ckb-testtool';
describe('my-contract', () => {
test('should work', async () => {
const resource = Resource.default();
const tx = Transaction.default();
// Deploy scripts and set up transaction
const mainScript = resource.deployCell(hexFrom(readFileSync(DEFAULT_SCRIPT_CKB_JS_VM)), tx, false);
// ... setup cells and verify
const verifier = Verifier.from(resource, tx);
await verifier.verifySuccess(true);
});
});Requires running local devnet via offckb:
offckb node # Start local devnet
pnpm test -- devnet # Run devnet tests- devnet: Local development (default, via offckb)
- testnet: Public test network
- mainnet: Production network
pnpm run deploy -- --network <network> [--type-id] [--privkey 0x...]--type-id: Enable upgradable contracts via Type ID pattern--privkey: Custom private key (defaults to offckb deployer)
After deployment, deployment/scripts.json contains:
{
"devnet": {
"hello-world.bc": {
"codeHash": "0x...",
"hashType": "type",
"cellDeps": [...]
}
}
}The Next.js app uses CCC (Common Chain Connector) for wallet integration:
app/utils/ckbClient.ts- CKB client setupapp/utils/contract.ts- Contract interaction helpersapp/components/ConnectWallet.tsx- Wallet connection UI
import scripts from "@/deployment/scripts.json";
import systemScripts from "@/deployment/system-scripts.json";
// Build script args for ckb-js-vm
const mainScript = {
codeHash: systemScripts.devnet["ckb_js_vm"].script.codeHash,
hashType: systemScripts.devnet["ckb_js_vm"].script.hashType,
args: hexFrom(
"0x0000" +
scripts.devnet["hello-world.bc"].codeHash.slice(2) +
hashTypeToBytes(scripts.devnet["hello-world.bc"].hashType).slice(2) +
"your_custom_args"
),
};pnpm run add-contract token-transferThen implement logic in contracts/token-transfer/src/index.ts
Common patterns:
- Type Script: Validates cell creation/destruction rules
- Lock Script: Validates who can spend a cell
- Deploy contract:
pnpm run deploy -- --network devnet - Import in frontend:
import scripts from "@/deployment/scripts.json" - Build transaction using CCC library
pnpm run build:debug # Build with debug symbols
pnpm run deploy:debug # Deploy debug version| Concept | Description |
|---|---|
| Cell | Basic data unit (like UTXO with data) |
| Lock Script | Defines who can spend the cell |
| Type Script | Defines rules for cell creation/destruction |
| Capacity | CKB tokens, also determines cell storage size |
| Cell Dep | Reference to code/data cells |
| Witness | Signature/proof data |
The .skills/ folder contains structured patterns following the Agent Skills Open Standard. These provide detailed, reusable patterns for AI assistants.
| Skill | Description | Use When |
|---|---|---|
ckb-contract-patterns |
Smart contract patterns | Writing/reviewing contracts |
ckb-ccc-frontend |
Frontend integration | Building dApp frontends |
.skills/{skill-name}/
├── SKILL.md # Main skill definition
├── rules/ # Individual pattern files
│ ├── _sections.md # Section metadata
│ └── *.md # Pattern rules
├── metadata.json # Version info
└── README.md # Documentation
Contract Patterns (ckb-contract-patterns):
- Cell iteration with try/catch loops
- Token sum validation for UDT
- Contract structure with main() and exit()
Frontend Patterns (ckb-ccc-frontend):
- Network switching via
.env(devnet/testnet/mainnet) - CCC Provider setup in React/Next.js
- Wallet connection with
ccc.useCcc()andccc.useSigner() - Transaction composition with ckb-js-vm args format
- RPC calls to fetch cells and send transactions