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

# Create a Collection

This guide shows how to create an NFT collection using JavaScript with the Coinbase CDP SDK and viem.

## Try it Out

### V0 Prototype

You can try out a working prototype of the Coinbase Smart Wallet at:
[Coinbase Wallet V0 Prototype](https://v0-coinbase-wallet-prototype.vercel.app/)

### Deploy Your Own

Deploy your own version of the prototype with one click:

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fsweetmantech%2Fcoinbase-wallet-v2-app\&env=CDP_API_KEY_ID,CDP_API_KEY_SECRET,CDP_WALLET_SECRET,CDP_PAYMASTER_URL)

## Prerequisites

* Coinbase API credentials (API Key ID and Secret)
* A wallet secret for authentication
* Node.js environment

## Installation

```bash theme={null}
npm install @coinbase/cdp-sdk viem
```

## Creating a Collection

The following example demonstrates how to create a new NFT collection using the Coinbase CDP SDK and viem:

```javascript theme={null}
import { CdpClient } from "@coinbase/cdp-sdk";
import { type Address, encodeFunctionData } from "viem";

// ABI for the token contract (create function)
const tokenAbi = [
  {
    inputs: [
      { internalType: "string", name: "newContractURI", type: "string" },
      { internalType: "string", name: "name", type: "string" },
      {
        components: [
          { internalType: "uint32", name: "royaltyMintSchedule", type: "uint32" },
          { internalType: "uint32", name: "royaltyBPS", type: "uint32" },
          { internalType: "address", name: "royaltyRecipient", type: "address" },
        ],
        internalType: "struct ICreatorRoyaltiesControl.RoyaltyConfiguration",
        name: "defaultRoyaltyConfiguration",
        type: "tuple",
      },
      { internalType: "address payable", name: "defaultAdmin", type: "address" },
      { internalType: "bytes[]", name: "setupActions", type: "bytes[]" },
    ],
    name: "createContract",
    outputs: [{ internalType: "address", name: "", type: "address" }],
    stateMutability: "nonpayable",
    type: "function",
  },
] as const;

// Main function to create a collection
async function createCollection() {
  // Initialize CDP client with your credentials
  const cdp = new CdpClient({
    apiKeyId: process.env.CDP_API_KEY_ID,
    apiKeySecret: process.env.CDP_API_KEY_SECRET,
    walletSecret: process.env.CDP_WALLET_SECRET,
  });

  // Create a new account
  const evmAccount = await cdp.evm.createAccount();

  // Create a smart account (contract wallet)
  const smartAccount = await cdp.evm.createSmartAccount({
    owner: evmAccount,
  });

  // Collection details
  const contractUri = "ar://contractUri"; // Your contract metadata URI
  const collectionName = "My NFT Collection"; // Your collection name

  // Royalty configuration
  const royaltyConfig = {
    royaltyMintSchedule: 0,
    royaltyBPS: 0, // 0% royalties (set to 1000 for 10%)
    royaltyRecipient: smartAccount.address,
  };

  // Encode the function call data
  const createContractData = encodeFunctionData({
    abi: tokenAbi,
    functionName: "createContract",
    args: [
      contractUri,
      collectionName,
      royaltyConfig,
      smartAccount.address, // defaultAdmin
      [], // setupActions
    ],
  });

  // Send the transaction
  const sendResult = await cdp.evm.sendUserOperation({
    smartAccount,
    network: "base-sepolia", // supported networks: https://docs.cdp.coinbase.com/api/docs/networks#network-identifiers
    paymasterUrl: process.env.CDP_PAYMASTER_URL,
    calls: [
      {
        to: "0x6832A997D8616707C7b68721D6E9332E77da7F6C" as Address, // Contract factory address
        data: createContractData,
      },
    ],
  });

  // Wait for the transaction to be mined
  await cdp.evm.waitForUserOperation({
    smartAccountAddress: smartAccount.address,
    userOpHash: sendResult.userOpHash,
  });

  // Get the transaction details
  const userOp = await cdp.evm.getUserOperation({
    smartAccount,
    userOpHash: sendResult.userOpHash,
  });

  return {
    smartAccountAddress: smartAccount.address,
    transactionHash: userOp.transactionHash,
  };
}

// Call the function to create a collection
createCollection()
  .then(result => console.log("Collection created:", result))
  .catch(error => console.error("Error creating collection:", error));
```

## Environment Variables

Make sure to set the following environment variables:

```
CDP_API_KEY_ID=your_api_key_id
CDP_API_KEY_SECRET=your_api_key_secret
CDP_WALLET_SECRET=your_wallet_secret
CDP_PAYMASTER_URL=your_paymaster_url
```

## Next Steps

After creating your collection, you can:

* Mint NFTs within your collection
* Set up sales configurations
* Update collection metadata
* Add collection to marketplaces
