Skip to main content
This flow outlines the steps involved when a creator mints a completely new digital asset (not derived from another) using the Cultura SDK. This typically involves preparing metadata, uploading it to IPFS, and then calling the SDK’s minting function.

Flow Diagram

Explanation

  1. User Initiates: The user interacts with the dApp, providing details like the asset’s name, description, and optionally an image file or URL.
  2. SDK Call (Dapp): The dApp calls the SDK’s mintDigitalAsset function. It passes:
    • The recipient address (to).
    • Asset name and description.
    • An empty array ([]) for parentDigitalAssets (indicating it’s an original asset).
    • A terms object containing asset-specific terms or extended metadata (e.g., { creatorTerms: "...", usageRights: "..." }). This is distinct from the standard ERC721 metadata.
    • A tokenURI object containing standard ERC721 metadata (e.g., { name, description, image: imageUrl }).
  3. Metadata Upload (SDK): If objects were passed for terms and tokenURI, the SDK uploads them to IPFS automatically, obtaining termsURI and tokenURI CIDs. If strings (pre-existing URIs) were passed, the SDK uses them directly.
  4. Contract Interaction (SDK): The SDK calls the safeMint function on the CulturaDigitalAsset contract, passing the recipient, name, description, empty parentDigitalAssets array, and the final termsURI and tokenURI.
  5. Minting (Contract): The CulturaDigitalAsset contract performs the mint operation:
    • Creates a new token.
    • Assigns ownership to the recipient (to).
    • Stores the provided digitalAssetName, digitalAssetDescription, parentDigitalAssets (empty), termsURI (intended for specific terms/metadata), and tokenURI (standard ERC721 metadata URI) within its internal data structures.
    • Emits a standard ERC721 Transfer event indicating the creation of the new token ID.
  6. Result (SDK/Dapp): The SDK waits for the transaction receipt, extracts the tokenId from the Transfer event log, and returns it to the dApp. The dApp then notifies the user of the successful minting.
  7. Post-Minting: The asset now exists on-chain at Level 0. The next step to make it licensable is the Verification & Attestation Flow.

SDK Snippet Example

import { CulturaSDK } from "@cultura/sdk";
// Note: The SDK's mintDigitalAsset handles metadata upload internally.
// You might still use uploadFileToIpfs separately for the actual asset file (image, audio etc.)
// import { uploadFileToIpfs } from "@cultura/sdk";

async function mintOriginalAsset(
  sdk: CulturaSDK,
  recipientAddress: `0x${string}`,
  assetName: string,
  assetDescription: string,
  imageUrl?: string // Optional: URL of the image already uploaded to IPFS or elsewhere
) {
  try {
    // 1. Prepare metadata objects
    const termsObject = {
      // Define the specific terms or extended metadata for this asset
      // This is separate from the standard ERC721 metadata below.
      // Example:
      creatorDefinedField: "Some value",
      usageRestrictions: "Non-commercial use only",
    };
    const tokenUriObject = {
      // Standard ERC721 metadata
      name: assetName,
      description: assetDescription,
      image: imageUrl, // Include the image URL here
      // ... other standard ERC721 fields
    };

    // 2. Call the SDK's mint function with metadata objects
    // The SDK will handle uploading these objects to IPFS.
    // Pass an empty array for parentDigitalAssets for original assets.
    const tokenId = await sdk.culturaDigitalAsset.mintDigitalAsset(
      recipientAddress,
      assetName, // Name is also passed directly to the contract
      assetDescription, // Description is also passed directly
      [], // Empty array signifies an original asset
      termsObject, // Pass the terms object for IPFS upload
      tokenUriObject // Pass the tokenURI object for IPFS upload
    );

    console.log(
      `Successfully minted original asset "${assetName}" with Token ID: ${tokenId}`
    );
    return tokenId;
  } catch (error) {
    console.error("Error minting original asset:", error);
    // Handle error appropriately
  }
}

// --- Usage ---
// Assuming 'sdk' is an initialized CulturaSDK instance with a wallet
// const sdk = CulturaSDK.createWithWallet(window.ethereum, { chain: 'testnet' });
// const userAddress = await sdk.walletClient?.getAddresses()[0];
// if (sdk && userAddress) {
//   mintOriginalAsset(sdk, userAddress);
// }