Skip to main content

Basics

Joystiq relies on project-relative paths, meaning that any time you pass a folder name (e.g. my-drop), it looks for a structure like this:

my-drop/
├── config.json # Your main collection configuration
├── artifacts.json # All deployed IDs and contract references (auto-generated)
├── metadata.json # Generated after `metadata upload`
├── .arweave # Log file from arweave asset upload (auto-generated)
├── .walrus # Log file from walrus asset upload (auto-generated)
├── .metadata # Log file from metadata upload (auto-generated)
├── assets/ # (Optional) NFT media files (images, videos, etc.) used by `arweave upload` or `walrus upload`

Project Folder Expectations

When you run a command like:

joystiq metadata arweave upload ./my-drop

Joystiq will assume:

  • ./my-drop/config.json exists and defines your collection.
  • ./my-drop/assets/ contains files to upload (if you're using arweave upload).
  • All output (logs and deployed IDs) will also be written back inside ./my-drop.

config.json

This file defines your entire NFT collection and mint phases. Example:

{
"collection_name": "teset",
"collection_description": "desec",
"collection_media_url": "https://arweave.net/...",
"supply": "8",
"fixed_metadata": false,
"royalty_percent": "5",
"royalty_wallet": "0xe8c9...e6895a",
"is_immutable": false,
"start_order": "1",
"groups": [
{
"name": "public",
"merkle_root": null,
"max_mints_per_wallet": "0",
"reserved_supply": "0",
"payments": [
{
"coin": "0x2::sui::SUI",
"routes": [
{
"method": "transfer",
"amount": "100001",
"destination": "0xe8c9...e6895a"
}
]
}
],
"start_time": "2025-07-09T06:03:42Z",
"end_time": null
}
]
}

You may define multiple groups (phases), each with their own start time, payment method, and allowlist setup (via Merkle root). Joystiq doesn’t care where or how you generate that root. It only needs the final value.


artifacts.json

This file is auto-generated during deployment and contains all on-chain object IDs used by the collection. It includes:

  • The jq721 contract package ID (user-deployed)
  • The core contract object ID (static/shared)
  • The collection object ID
  • Policy object, core config, kiosk types, and more

Example:

{
"packageID": "0xabc...",
"collectionObjectID": "0x123...",
"collectionJqCoreConfigID": "0x456...",
"policyID": "0x789..."
}

This file is critical for your mint UI. You must copy its contents into your frontend (especially when launching a live mint).


assets/

This optional folder holds your media (e.g. 0.png, 1.png, etc.). If you're using joystiq arweave upload, Joystiq will upload files from here and embed URLs back into your metadata.

Make sure filenames match the corresponding metadata file (e.g. 0.png0.json).


Logs

After uploading metadata or assets, Joystiq will generate the following logs:

  • .metadata Contains mapping of local files to on-chain object IDs or upload hashes.
  • .arweave Contains mappings of asset files to final URLs (e.g. Arweave links).
  • metadata.json Final combined list of token metadata, generated by Joystiq.

These logs are used in later steps (e.g. setting metadata, reusing uploads, or verifying mints).


TL;DR

File/FolderPurpose
config.jsonDefines collection config & mint phases
assets/Optional images or media to be uploaded
artifacts.jsonAll deployed contract/object references
metadata.jsonFinal metadata output (after upload)
.metadata / .arweaveInternal upload logs

Joystiq is strict about paths. If you pass ./my-drop, it expects to find all related files and folders inside that directory.