======================== CODE SNIPPETS ======================== TITLE: DOB Cookbook Example Markdown Documentation Template DESCRIPTION: A comprehensive template for the Markdown documentation file (`.md`) required for each new example. It includes sections for an introduction, code reference, on-chain test cluster links, platform preview images and links, and a compatibility table. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/CONTRIBUTING.md#_snippet_2 LANGUAGE: markdown CODE: ``` ## 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) | |:---------------------------------------|----------------------------------------:|
``` ---------------------------------------- TITLE: DOB Cookbook Example File Structure DESCRIPTION: Defines the required file structure for organizing new examples within the DOB Cookbook, separating core implementation (TypeScript) from documentation (Markdown) based on DOB protocol versions. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/CONTRIBUTING.md#_snippet_1 LANGUAGE: APIDOC CODE: ``` examples/ dob{0|1}/ {index}.{example-name}.ts # Core implementation {index}.{example-name}.md # Documentation ``` ---------------------------------------- TITLE: Setup and Utility Functions for CKB Explorer and DNA Generation DESCRIPTION: This snippet includes necessary imports from `@ckb-ccc/ccc` and `@ckb-ccc/playground` and defines two helper functions. `getExplorerTxUrl` constructs a CKB explorer URL for a given transaction hash, adapting to mainnet or testnet. `generateSimpleDNA` creates a random hexadecimal string of a specified length, commonly used as a DNA for digital objects. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/0.basic-shape.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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(''); } ``` ---------------------------------------- TITLE: Commit and Push Changes for Example Submission DESCRIPTION: Commands to stage all modified files, commit them with a descriptive message following conventional commits, and push the changes to your remote repository as part of the submission process. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/CONTRIBUTING.md#_snippet_3 LANGUAGE: bash CODE: ``` git add . git commit -m "feat: add {example-name} example" git push ``` ---------------------------------------- TITLE: On-chain Testnet Cluster and DOB Details DESCRIPTION: Details of a deployed Spore cluster and a minted DOB on the CKB Testnet, including transaction hashes, cluster IDs, and Spore IDs. These can be used to verify the on-chain assets created by the example. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/5.regular-link-svg.md#_snippet_1 LANGUAGE: APIDOC CODE: ``` Testnet: - createCluster tx: https://testnet.explorer.nervos.org/transaction/0x20129fa511e7e2ceaa6491e8a6f83b75db4558a083601a21a0897a97cd23f135 - clusterId: 0x3ae41180f64a22ad6c73058d27f956f8195c17bab3bc03222b5e5683771407c4 (type_script.args) - clusterTypeHash: 0x574c7a019d7cbb584e2f75ed69f69047de6a2dd1b0fb2da3b1153c11155ce12a (hash(type_script(cluster cell))) - mintSpore tx: https://testnet.explorer.nervos.org/transaction/0x8d355897d8e907933cdaa7448f1f8ba10aa412c69b58ebe7dc151ae5867ead26 - sporeId: 0x2bc5d6ca4084ea4d7eff02764d84df4be116cfbbb20e2ca4704a636e13a9d4d9 (type_script.args) - sporeTypeHash: 0xbd03eafbd4fce08923ead64bd0629ce0635262ff2f83aa536a34902a658d6a3d (hash(type_script(spore cell))) ``` ---------------------------------------- TITLE: Create DOB with Regular Image URLs using DOB/0 Protocol (TypeScript) DESCRIPTION: This TypeScript example demonstrates the creation of a Digital Object (DOB) using the DOB/0 protocol. It includes functions to generate a simple DNA string, construct a cluster description with specific traits (`prev.type`, `prev.bg`), and then create both a Spore cluster and a Spore (DOB) on the CKB blockchain, using regular image URLs for rendering. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/5.regular-link-svg.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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}`); ``` ---------------------------------------- TITLE: Create Spore Cluster on CKB DESCRIPTION: Demonstrates how to create a Spore Cluster on the CKB network. It uses the `generateClusterDescriptionUnderDobProtocol` function to define the cluster's properties, completes the transaction fee, sends the transaction, and waits for its commitment, logging the transaction hash and cluster ID. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/4.ipfs-png.md#_snippet_2 LANGUAGE: typescript CODE: ``` /** * 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}`); ``` ---------------------------------------- TITLE: Utility Functions for CKB Explorer and DNA Generation DESCRIPTION: Provides helper functions to construct CKB Explorer transaction URLs based on the network (mainnet/testnet) and to generate simple hexadecimal DNA strings of a specified length for DOB content. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/4.ipfs-png.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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(''); } ``` ---------------------------------------- TITLE: Generate DOB/0 Cluster Description DESCRIPTION: Defines the structure for a DOB/0 cluster description, specifying traits like 'prev.type', 'prev.bg' (using an IPFS image link), 'Type', and 'Timestamp'. It then encodes this description for the Spore protocol, enabling the cluster to define rendering rules for associated DOBs. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/4.ipfs-png.md#_snippet_1 LANGUAGE: typescript CODE: ``` /** * 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); } ``` ---------------------------------------- TITLE: Setup and Utility Functions for DOB Creation DESCRIPTION: This snippet initializes the CKB CCC library and playground client/signer, essential for interacting with the CKB network. It also provides helper functions: `getExplorerTxUrl` constructs a CKB explorer URL for a given transaction hash, adapting for mainnet or testnet, and `generateSimpleDNA` creates a random hexadecimal string of a specified length, used for generating unique DOB DNA. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/8.btcfs-i1-svg.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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(''); } ``` ---------------------------------------- TITLE: Create Spore Cluster and Mint Spore with DOB Content DESCRIPTION: This snippet demonstrates the end-to-end process of creating a Spore cluster and then minting a Spore within that cluster. It first creates a cluster with a name and a dynamically generated DOB description. Subsequently, it mints a new Spore, assigning it a `dob/0` content type and a randomly generated DNA, linking it to the newly created cluster. Finally, it sends and waits for both transactions to be committed on the CKB blockchain, logging their explorer URLs and IDs. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/0.basic-shape.md#_snippet_2 LANGUAGE: typescript CODE: ``` /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "dob1-basic-shape", description: generateClusterDescriptionUnderDobProtocol() } }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0xc2e4164c6b390b0ca31138d1715201c24dc9aafae1a75b1047763cd06602de4e'; 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(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}`); ``` ---------------------------------------- TITLE: Mint Spore (DOB) with IPFS Content DESCRIPTION: Illustrates the process of minting a new Spore, which acts as a Digital Object (DOB). It sets the content type to 'dob/0', embeds a randomly generated DNA, and associates the Spore with a previously created cluster. The code handles transaction fee completion, sending, and waiting for transaction commitment. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/4.ipfs-png.md#_snippet_3 LANGUAGE: typescript CODE: ``` /** * 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}`); ``` ---------------------------------------- TITLE: Clone DOB Cookbook Repository DESCRIPTION: Instructions to clone your forked DOB Cookbook repository from GitHub and navigate into its directory for local development. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/CONTRIBUTING.md#_snippet_0 LANGUAGE: bash CODE: ``` git clone https://github.com/YOUR-USERNAME/dob-cookbook.git cd dob-cookbook ``` ---------------------------------------- TITLE: Spore Protocol Platform Compatibility Matrix DESCRIPTION: A compatibility matrix indicating which platforms (JoyID, Omiga, CKB Explorer, Mobit, Dobby) support Spore Protocol assets on both Testnet and Mainnet, providing a quick reference for users. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/3.btcfs-i0-png.md#_snippet_6 LANGUAGE: APIDOC CODE: ``` | | JoyID | Omiga | CKB Explorer | Mobit | Dobby | | ------- | ----- | ----- | ------------ | ----- | ----- | | Testnet | βœ… | βœ… | βœ… | βœ… | βœ… | | Mainnet | βœ… | βœ… | βœ… | βœ… | βœ… | ``` ---------------------------------------- TITLE: Basic DOB Protocol Usage: Create Cluster and Mint DOB DESCRIPTION: This TypeScript code demonstrates the end-to-end process of interacting with the DOB protocol. It includes helper functions for generating DNA and explorer URLs, defining a DOB0 pattern for cluster description, and then executing transactions to create a Spore cluster and mint a DOB (Spore) within that cluster. It relies on the @ckb-ccc/ccc and @ckb-ccc/playground libraries. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/0.basic-loot.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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}`); ``` ---------------------------------------- TITLE: Utility Functions for CKB Explorer and DNA Generation DESCRIPTION: Helper functions to construct CKB Explorer transaction URLs for both mainnet and testnet, and to generate simple hexadecimal DNA strings of a specified length. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/3.btcfs-i0-png.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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(''); } ``` ---------------------------------------- TITLE: Get Cluster Type Hash for Cluster ID DESCRIPTION: This helper function calculates the type hash for a Spore cluster based on a given Cluster ID and an optional Spore version. It retrieves cluster script information to construct the script and compute its hash. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/9.programmatic-img.md#_snippet_6 LANGUAGE: TypeScript CODE: ``` const getClusterTypeHash = (clusterId: string, version?: ccc.spore.SporeVersion | ccc.spore.SporeVersion.V2 ) => { const clusterScriptInfo = ccc.spore.getClusterScriptInfo(client, version) const clusterTypeScript = ccc.Script.from({ codeHash: clusterScriptInfo.codeHash, hashType: clusterScriptInfo.hashType, args: clusterId }) return clusterTypeScript.hash(); } ``` ---------------------------------------- TITLE: Get DOB Type Hash for Spore ID DESCRIPTION: This helper function calculates the type hash for a DOB (Digital Object Blueprint) based on a given Spore ID and an optional Spore version. It uses the Spore script information to construct the script and derive its hash. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/9.programmatic-img.md#_snippet_5 LANGUAGE: TypeScript CODE: ``` const getDobTypeHash = (sporeId: string, version?: ccc.spore.SporeVersion | ccc.spore.SporeVersion.V2 ) => { const sporeScriptInfo = ccc.spore.getSporeScriptInfo(client, version) const dobTypeScript = ccc.Script.from({ codeHash: sporeScriptInfo.codeHash, hashType: sporeScriptInfo.hashType, args: sporeId }) return dobTypeScript.hash(); } ``` ---------------------------------------- TITLE: Create Spore Cluster for DOB/0 Protocol DESCRIPTION: This code demonstrates how to create a Spore Cluster, which acts as a container for DOBs. It uses the `ccc.spore.createSporeCluster` function, providing a name and the previously generated DOB/0 cluster description. The transaction is then completed with a fee, sent to the network, and the script waits for its commitment, logging the transaction hash and cluster ID. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/2.regular-link-png.md#_snippet_1 LANGUAGE: typescript CODE: ``` /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "Regular link 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}`); ``` ---------------------------------------- TITLE: Testnet On-chain Cluster and DOB Details DESCRIPTION: Provides details for a sample cluster and DOB (Spore) on the CKB Testnet, including transaction hashes, cluster IDs, and type hashes for verification on explorers. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/4.nervape-compose(btcfs).md#_snippet_7 LANGUAGE: APIDOC CODE: ``` Testnet: createCluster tx ``` ---------------------------------------- TITLE: Define DOB0 and DOB1 Patterns and Generate Cluster Description DESCRIPTION: This function, `generateClusterDescriptionUnderDobProtocol`, defines the structure for Digital Object Blueprint (DOB) patterns, specifically DOB0 and DOB1. DOB0 defines basic traits like 'Shape' and 'BackgroundColor' using string options. DOB1 maps these traits to SVG elements and attributes, allowing for dynamic visual representation based on DNA. The function then encodes these patterns into a cluster description suitable for the Spore protocol. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/0.basic-shape.md#_snippet_1 LANGUAGE: typescript CODE: ``` function generateClusterDescriptionUnderDobProtocol() { /** * Generation example for DOB0 */ const clusterDescription = "This is a basic-shape example for dob1."; const dob0Pattern: ccc.spore.dob.PatternElementDob0[] = [ { traitName: "Shape", dobType: "String", dnaOffset: 1, dnaLength: 1, patternType: "options", traitArgs: ["circle", "square", "triangle", "star", "text"] }, { traitName: "BackgroundColor", dobType: "String", dnaOffset: 0, dnaLength: 1, patternType: "options", traitArgs: ["red", "blue", "green", "yellow", "pink"] } ]; /** * Generation example for DOB1 */ const dob1Pattern: ccc.spore.dob.PatternElementDob1[] = [ { imageName: "IMAGE.0", svgFields: "attributes", traitName: "", patternType: "raw", traitArgs: "xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500'" }, { imageName: "IMAGE.0", svgFields: "elements", traitName: "BackgroundColor", patternType: "options", traitArgs: [ ["red", ""], ["blue", ""], ["green", ""], ["yellow", ""], [["*"], ""] ] }, { imageName: "IMAGE.0", svgFields: "elements", traitName: "Shape", patternType: "options", traitArgs: [ ["circle", ""], ["square", ""], ["triangle", ""], ["star", ""], ["text", "DOB1"], [["*"], ""] ] } ]; const dob1: ccc.spore.dob.Dob1 = { description: clusterDescription, dob: { ver: 1, decoders: [ { decoder: ccc.spore.dob.getDecoder(client, "dob0"), pattern: dob0Pattern }, { decoder: ccc.spore.dob.getDecoder(client, "dob1"), pattern: dob1Pattern } ] } }; return ccc.spore.dob.encodeClusterDescriptionForDob1(dob1); } ``` ---------------------------------------- TITLE: Create Spore Cluster and Mint Tiered Membership DOB (TypeScript) DESCRIPTION: This script demonstrates the end-to-end process of creating a Spore Cluster and minting a new Digital Object (DOB) on the CKB network. It includes helper functions for generating random DNA and explorer URLs, then executes the creation of a cluster and a DOB, completing fees, sending transactions, and waiting for their on-chain commitment. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/3.azuki-genesis(ipfs_bg_btcfs_icon).md#_snippet_1 LANGUAGE: TypeScript CODE: ``` 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(''); } /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "2.Azuki Genesis", description: generateClusterDescriptionUnderDobProtocol() } }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); /** * create spore */ //const clusterId = '0x69c4cbfa31bf6916fc456f4f9b78fbcc22dde28c326d0c7f05e78c723de97088'; 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}`); ``` ---------------------------------------- TITLE: Generate Spore DOB Viewing URLs for Multiple Platforms (TypeScript) DESCRIPTION: This TypeScript code snippet demonstrates how to construct a URL for viewing a Spore Digital Object (DOB) on various supported platforms (JoyID, Omiga, CKB Explorer, Dobby, Mobit). The `viewDobUrl` function dynamically generates the appropriate URL based on the platform, cluster ID, spore ID, and whether the environment is mainnet or testnet. It includes example usage to iterate through all supported platforms and log their respective viewing URLs. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/9.programmatic-img.md#_snippet_8 LANGUAGE: typescript CODE: ``` : `https://testnet.joyid.dev/nft/${sporeId.slice(2)}`; break; case PlatformSupportedDOB.OMIGA: const sporeTypeHash = getDobTypeHash(sporeId); url = isMainnet ? `https://omiga.io/info/dobs/${sporeTypeHash}` : `https://test.omiga.io/info/dobs/${sporeTypeHash}`; break; case PlatformSupportedDOB.CKBEXPLORER: const clusterTypeHash = getClusterTypeHash(clusterId); url = isMainnet ? `https://explorer.nervos.org/nft-info/${clusterTypeHash}/${sporeId}` : `https://testnet.explorer.nervos.org/nft-info/${clusterTypeHash}/${sporeId}`; break; case PlatformSupportedDOB.DOBBY: url = isMainnet ? `https://app.dobby.market/item-detail_ckb/${sporeId}` : `https://test-dobby.entrust3.com/item-detail_ckb/${sporeId}`; break; case PlatformSupportedDOB.MOBIT: url = isMainnet ? `https://mobit.app/dob/${sporeId.slice(2)}?chain=ckb` : `https://mobit.app/dob/${sporeId.slice(2)}?chain=ckb`; break; default: throw new Error(`Unsupported platform: ${platform}`); } return url; } 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)); }); ``` ---------------------------------------- TITLE: Create Colorful DOB with DOB/0 Protocol in TypeScript DESCRIPTION: This TypeScript example demonstrates how to create a Data Object Bundle (DOB) with custom background and text colors using the DOB/0 protocol. It involves generating a cluster description with specific `prev.bgcolor` and `prev<%k: %v>` traits for color customization, then creating a Spore cluster and minting a DOB (spore) with a simple DNA. The `prev.bgcolor` trait sets the background color, while `prev<%k: %v>` sets the text color and outputs the property name and value. The code also includes helper functions for generating DNA and CKB explorer URLs. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob0/1.colorful-loot.md#_snippet_0 LANGUAGE: typescript CODE: ``` 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: generateClusterDescriptionUnderDobDobProtocol(), }, }); 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}`); ``` ---------------------------------------- TITLE: TypeScript: Create Spore Cluster on CKB Network DESCRIPTION: Demonstrates how to create a Spore cluster using the CKB-CCC library. It initializes a cluster with a name and a dynamically generated DOB/1 description, then completes the transaction fee and sends the transaction to the network, logging the transaction hash and cluster ID. SOURCE: https://github.com/sporeprotocol/dob-cookbook/blob/main/examples/dob1/2.nervape-genesis(btcfs_bg_btcfs_icon).md#_snippet_2 LANGUAGE: typescript CODE: ``` /** * create cluster */ const { tx: clusterTx, id: clusterId } = await ccc.spore.createSporeCluster({ signer, data: { name: "2.Nervape Genesis", description: generateClusterDescriptionUnderDobProtocol(), }, }); await clusterTx.completeFeeBy(signer, 2000n); const clusterTxHash = await signer.sendTransaction(clusterTx); console.log("Create cluster tx sent:", clusterTxHash, `Cluster ID: ${clusterId}`); ```