### Example File Structure Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/CONTRIBUTING.md Organize new examples within the 'examples/' directory, separating DOB/0 and DOB/1 implementations. Each example should have a core TypeScript file and a Markdown documentation file. ```plaintext examples/ dob{0|1}/ {index}.{example-name}.ts # Core implementation {index}.{example-name}.md # Documentation ``` -------------------------------- ### Markdown Documentation Structure Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/CONTRIBUTING.md Structure your example's documentation using Markdown, including an introduction, embedded images, a link to the core code, on-chain transaction details, platform preview links, and a compatibility table. ```markdown ## Intro This example demonstrates [brief description of your example].
## [Code](./example-name.ts) // Your core implementation ## On-chain test cluster and DOB ### Testnet - πŸ‘‰[πŸ”— createCluster tx](https://testnet.explorer.nervos.org/transaction/your-tx-hash) - clusterId: `0x...` - clusterTypeHash: `0x...` - πŸ‘‰[πŸ”— mintSpore tx](https://testnet.explorer.nervos.org/transaction/your-tx-hash) - sporeId: `0x...` - sporeTypeHash: `0x...` ### Platform Preview(Testnet) #### JoyID ![example-joyid.png](../assets/images/dob1/example-joyid.png) [View on JoyID](https://testnet.joyid.dev/nft/...) #### Omiga ![example-omiga.png](../assets/images/dob1/example-omiga.png) [View on Omiga](https://test.omiga.io/info/dobs/...) #### CKB Explorer ![example-explorer.png](../assets/images/dob1/example-explorer.png) [View on Explorer](https://testnet.explorer.nervos.org/nft-info/...) #### Mobit ![example-mobit.png](../assets/images/dob1/example-mobit.png) [View on Mobit](https://mobit.app/dob/...) #### Dobby ![example-dobby.png](../assets/images/dob1/example-dobby.png) [View on Dobby](https://test-dobby.entrust3.com/item-detail_ckb/...) ## Compatibility | | JoyID | Omiga | CKB Explorer | Mobit | Dobby | | ------- | ----- | ----- | ------------ | ----- | ----- | | Testnet | βœ…or❌ | βœ…or❌| βœ…or❌ | βœ…or❌ | βœ…or❌| | Mainnet | ---
| [← Previous Example](prev-example.md) | [Next Example β†’](next-example.md) | |:---------------------------------------|----------------------------------------:|
``` -------------------------------- ### Create DOB Cluster and Spore with BTCFS i1 PNG Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/7.btcfs-i1-png.md This TypeScript code demonstrates creating a DOB cluster and minting spores using the DOB/0 protocol with BTCFS i1 PNG as the primary rendering object. It requires setup with @ckb-ccc/ccc and @ckb-ccc/playground. The code defines functions to generate cluster descriptions and simple DNA, then proceeds to create the cluster and mint spores, logging transaction hashes and IDs. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A cluster with btcfs i1 png as the primary rendering objects."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs:[ "btcfs://3bb2e97555eb1c54f379bcac51a201a18882188fb4c5e7b3aeed566088172f01i1", ], }, { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 2, dnaLength: 1, patternType: "options", traitArgs:[ "#C1C2C5", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 4, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "BTCFS i1 PNG", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0xa0af382231f3b48d92cd76d974e83df95c950269ea3257ffcadc49ba610ba980'; const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Create Cluster and Mint Spore with Custom Content Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob1/4.nervape-compose(btcfs).md This code snippet demonstrates the process of creating a cluster and then minting a Spore (DOB) with custom content. It requires a signer and uses the ckb-ccc SDK. Ensure you have the necessary setup for signer and ccc. ```typescript await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/1", content: ccc.bytesFrom(`{ \"dna\": \"${generateSimpleDNA(16)}\" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Create DOB/1 Cluster Configuration Source: https://context7.com/ckb-devrel/dob-cookbook/llms.txt Configures a DOB/1 cluster by defining its version and providing decoders for both DOB/0 and DOB/1 patterns. This setup is essential for dynamic SVG generation. ```typescript // Create DOB/1 cluster with both decoders const dob1: ccc.spore.dob.Dob1 = { description: "This is a basic-shape example for DOB/1.", dob: { ver: 1, decoders: [ { decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, { decoder: ccc.spore.dob.getDecoder(client, "dob1"), pattern: dob1Pattern, }, ], }, }; ``` -------------------------------- ### Create DOB Cluster and Spore with BTCFS PNG Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/3.btcfs-i0-png.md This TypeScript code demonstrates how to create a DOB cluster and mint a spore using btcfs:// image links. It requires the @ckb-ccc/ccc and @ckb-ccc/playground libraries. Ensure you have the necessary signer and client configurations. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A cluster with btcfs png as the primary rendering objects."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs:[ "btcfs://545b94cb1ecf2175b81c601346e4a7e05149cafc6f235330c9918e35f920e109i0", ], }, { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 2, dnaLength: 1, patternType: "options", traitArgs:[ "#E0E1E2", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 4, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "BTCFS PNG", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0x4ec09e267a50a2bdee7efa44e1978f416e5ca617b8c392b0027532bf0f7912b2'; const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Clone DOB Cookbook Repository Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/CONTRIBUTING.md Clone your forked repository to your local machine and navigate into the project directory. ```bash git clone https://github.com/YOUR-USERNAME/dob-cookbook.git cd dob-cookbook ``` -------------------------------- ### Create DOB/0 Cluster with Colorful Rendering Traits Source: https://context7.com/ckb-devrel/dob-cookbook/llms.txt Create a DOB/0 cluster with special rendering traits like `prev.bgcolor` for background color and `prev<%k: %v>` for text styling. This allows for custom visual appearances. Ensure `ccc` and `ccc/playground` are imported. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; // Define colorful DOB/0 pattern with rendering traits const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['#DBAB00', '#FFBDFC', '#09D3FF', '#AFE7F9', '#66C084'], }, { traitName: "prev<%k: %v>", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['#FFFFFF', '#000000', '#FFBDFC', '#000000', '#FFFFFF'] }, { traitName: "Type", dobType: "Number", dnaOffset: 1, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 2, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: "A colorful loot cluster", dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Colorful loot", description: ccc.spore.dob.encodeClusterDescriptionForDob0(dob0), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Colorful cluster created:", clusterId); ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/CONTRIBUTING.md Stage all your changes, commit them with a descriptive message, and push them to your forked repository. ```bash git add . git commit -m "feat: add {example-name} example" git push ``` -------------------------------- ### Create DOB Cluster and Mint DOB Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/0.basic-loot.md This TypeScript code demonstrates how to create a DOB cluster and mint a DOB spore using the ccc library. It includes functions for generating transaction URLs and simple DNA, defining DOB patterns, and handling cluster and spore creation transactions. Ensure you have the necessary ccc library and signer configured. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A simple loot cluster"; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "BackgroundColor", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ["red", "blue", "green", "black", "white"], }, { traitName: "Type", dobType: "Number", dnaOffset: 1, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 2, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Simple loot", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Create Colorful Loot Cluster and Spore Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/1.colorful-loot.md This script demonstrates creating a DOB cluster with custom background and text colors, then minting a spore associated with that cluster. It utilizes the ccc library for Spore protocol interactions. Ensure you have the necessary signer and client configurations from the @ckb-ccc/playground module. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A colorful loot cluster"; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['#DBAB00', '#FFBDFC', '#09D3FF', '#AFE7F9', '#66C084'], }, { traitName: "prev<%k: %v>", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['#FFFFFF', '#000000', '#FFBDFC', '#000000', '#FFFFFF'] }, { traitName: "Type", dobType: "Number", dnaOffset: 1, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 2, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Colorful loot", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Create DOB/0 Cluster with BTCFS Image Storage Source: https://context7.com/ckb-devrel/dob-cookbook/llms.txt Use this snippet to create a DOB/0 cluster that utilizes BTCFS for permanent, on-chain image storage. Ensure the `ccc` library and `ccc/playground` are imported. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; // Define DOB/0 pattern with BTCFS image reference const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs: [ "btcfs://545b94cb1ecf2175b81c601346e4a7e05149cafc6f235330c9918e35f920e109i0", ], }, { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 2, dnaLength: 1, patternType: "options", traitArgs: ["#E0E1E2"], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, ]; const dob0: ccc.spore.dob.Dob0 = { description: "A cluster with BTCFS PNG as the primary rendering objects.", dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "BTCFS PNG", description: ccc.spore.dob.encodeClusterDescriptionForDob0(dob0), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("BTCFS cluster created:", clusterId); ``` -------------------------------- ### Log DOB View URLs for All Supported Platforms Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/9.programmatic-img.md This code snippet iterates through all supported DOB platforms and logs the generated view URL for each. It requires the `viewDobUrl` function and the `PlatformSupportedDOB` enum to be defined. ```typescript console.log('Now you can view the dob on JoyId, Omiga, CKB Explorer, Mobit, Dobby...'); Object.values(PlatformSupportedDOB).forEach(platform => { console.log(`View on ${platform}: πŸ‘‰πŸ”—`, viewDobUrl(platform, clusterId, sporeId)); }); ``` -------------------------------- ### Create DOB Cluster and Spore with Regular Link SVG Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/5.regular-link-svg.md This code generates a DOB cluster and mints a spore using the DOB/0 protocol. It configures traits for image rendering and sets a background image. Ensure the ccc library and playground client/signer are imported. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A cluster with regular link svg as the primary rendering objects."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs:[ "https://www.nervos.org/favicon.svg", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 4, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Regular link SVG", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0x3ae41180f64a22ad6c73058d27f956f8195c17bab3bc03222b5e5683771407c4'; const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Configure and Create DOB/1 Spore Cluster Source: https://context7.com/ckb-devrel/dob-cookbook/llms.txt Configures the DOB/1 cluster with decoders for DOB/0 and DOB/1 patterns, then creates the Spore cluster using the defined data and uploads the transaction. ```typescript const dob1: ccc.spore.dob.Dob1 = { description: "A cluster with Nervape compose as the primary rendering objects.", dob: { ver: 1, decoders: [ { decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern }, { decoder: ccc.spore.dob.getDecoder(client, "dob1"), pattern: dob1Pattern }, ], }, }; const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Awesome Nervapes", description: ccc.spore.dob.encodeClusterDescriptionForDob1(dob1), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Composable DOB/1 cluster created:", clusterId); ``` -------------------------------- ### Create DOB/0 Cluster with IPFS Image Storage Source: https://context7.com/ckb-devrel/dob-cookbook/llms.txt This snippet creates a DOB/0 cluster using IPFS for decentralized content storage, offering a balance between decentralization and flexibility for media. Ensure necessary imports are present. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; // Define DOB/0 pattern with IPFS image reference const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs: [ "ipfs://QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, ]; const dob0: ccc.spore.dob.Dob0 = { description: "A cluster with IPFS PNG as the primary rendering objects.", dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "IPFS PNG", description: ccc.spore.dob.encodeClusterDescriptionForDob0(dob0), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("IPFS cluster created:", clusterId); ``` -------------------------------- ### Create DOB Cluster and Mint Spore with IPFS PNG Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/4.ipfs-png.md This TypeScript code uses the ccc library to create a DOB cluster and mint a spore. It defines a DOB pattern for IPFS PNGs and generates a simple DNA. Ensure you have the necessary signer and client configurations from @ckb-ccc/playground. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A cluster with ipfs png as the primary rendering objects."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs:[ "ipfs://QmRRPWG96cmgTn2qSzjwr2qvfNEuhunv6FNeMFGa9bx6mQ", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 4, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "IPFS PNG", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0x63667a454c67ae31ad9acca4ad5798004eb62fbc047dceee6913c8c5fca91e91'; const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ``` -------------------------------- ### Create DOB Cluster and Spore with BTCFS i1 SVG Source: https://github.com/ckb-devrel/dob-cookbook/blob/main/examples/dob0/8.btcfs-i1-svg.md This TypeScript code creates a DOB cluster and mints a spore using btcfs i1 SVG as the primary rendering object. It requires the @ckb-ccc/ccc and @ckb-ccc/playground libraries. Ensure you have the necessary signer and client configurations. ```typescript import { ccc } from "@ckb-ccc/ccc"; import { client, signer } from "@ckb-ccc/playground"; function getExplorerTxUrl(txHash: string) { const isMainnet = client.addressPrefix === 'ckb'; const baseUrl = isMainnet ? 'https://explorer.nervos.org' : 'https://testnet.explorer.nervos.org'; return `${baseUrl}/transaction/${txHash}` } function generateSimpleDNA(length: number): string { return Array.from( { length }, () => Math.floor(Math.random() * 16).toString(16) ).join(''); } /** * Generate cluster description */ function generateClusterDescriptionUnderDobProtocol() { const clusterDescription = "A cluster with btcfs i1 svg as the primary rendering objects."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "prev.type", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ['image'], }, { traitName: "prev.bg", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs:[ "btcfs://8ca2da44996f5a06ad44b5bb87fd9acb71390b6c0cb1910c10b0deb8daad7f82i1", ], }, { traitName: "prev.bgcolor", dobType: "String", dnaOffset: 2, dnaLength: 1, patternType: "options", traitArgs:[ "#FFC103", ], }, { traitName: "Type", dobType: "Number", dnaOffset: 3, dnaLength: 1, patternType: "range", traitArgs: [10, 50], }, { traitName: "Timestamp", dobType: "Number", dnaOffset: 4, dnaLength: 4, patternType: "rawNumber", }, ]; const dob0: ccc.spore.dob.Dob0 = { description: clusterDescription, dob: { ver: 0, decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern, }, }; return ccc.spore.dob.encodeClusterDescriptionForDob0(dob0); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "BTCFS i1 SVG", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); await signer.client.waitTransaction(clusterTxHash); console.log("Create cluster tx committed:", getExplorerTxUrl(clusterTxHash), `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0x8a72b43b66a01aefe6e7ad7258112c63950955f1b07a098b6392278186fe0809'; const { tx: sporeTx, id: sporeId } = await ccc.spore.createSpore({ signer, data: { contentType: "dob/0", content: ccc.bytesFrom(`{ "dna": "${generateSimpleDNA(16)}" }`, "utf8"), clusterId: clusterId, }, clusterMode: "clusterCell", }); await sporeTx.completeFeeBy(signer, 2000n); const sporeTxHash = await signer.sendTransaction(sporeTx); console.log("Mint DOB tx sent:", sporeTxHash, `Spore ID: ${sporeId}`); await signer.client.waitTransaction(sporeTxHash); console.log("Mint DOB tx committed:", getExplorerTxUrl(sporeTxHash), `Spore ID: ${sporeId}`); ```