> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cultura.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Minting an Original Digital Asset

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

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Dapp
    participant SDK
    participant IPFS
    participant DigitalAssetContract

    User->>Dapp: Initiates minting process (provides name, desc, image file/URL)
    Dapp->>SDK: Calls mintDigitalAsset(to, name, desc, [], termsObj, tokenUriObj)
    activate SDK
    %% SDK handles uploads internally if objects are passed
    SDK->>IPFS: Uploads termsObj (if object)
    activate IPFS
    IPFS-->>SDK: Returns termsURI
    deactivate IPFS
    SDK->>IPFS: Uploads tokenUriObj (if object)
    activate IPFS
    IPFS-->>SDK: Returns tokenURI
    deactivate IPFS
    SDK->>DigitalAssetContract: safeMint(to, name, desc, [], termsURI, tokenURI)
    activate DigitalAssetContract
    DigitalAssetContract-->>SDK: Emits Transfer event with tokenId
    deactivate DigitalAssetContract
    SDK-->>Dapp: Returns tokenId
    deactivate SDK
    Dapp-->>User: Displays success and new tokenId
```

## 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](./verification-attestation).

## SDK Snippet Example

```typescript theme={null}
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);
// }
```
