Skip to content

About

CLI toolset for mass-uploading images to Swarm, generating ERC-1155 metadata, minting NFTs on the OpenRun contract, and syncing NFT data to MySQL

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

23 Commits

Folders and files

Repository files navigation

OpenRun NFT Tools

CLI toolset for mass-uploading images to Swarm (decentralized storage), generating ERC-1155 metadata, minting NFTs on the OpenRun contract, and syncing NFT data to MySQL.

Prerequisites

  • Node.js (v18+)
  • npm
  • A running Bee node (light or full mode) with a usable postage stamp batch
  • A Swarm gateway URL for public reads (your own node-backed gateway or the public https://api.gateway.ethswarm.org)
  • Access to an OpenRun ERC-1155 contract (Base Sepolia)
  • MySQL database (for sync-db step)

Installation

npm install
cp .env.example .env
# Edit .env with your credentials

How storage works

  • Every image is uploaded individually and gets its own permanent, content-addressed Swarm reference (64-char hex). Nested category subfolders are flattened — each file inside becomes its own item.
  • References never change: adding new images later doesn't disturb existing ones, and re-uploading identical content is free (chunks are deduplicated by content address).
  • Uploads are pinned on the Bee node (pin: true) so its garbage collection never evicts content your gateway serves, and pushed to the network synchronously (deferred: false).
  • Public URLs are built as ${SWARM_GATEWAY_URL}/bzz/<ref> — used in each metadata image field and the contract baseURI.
  • Image basenames must be unique per parent folder (avatar/, thumbnail/): token IDs are keccak256("<parent>/<name>"), so upload-images fail-fast aborts if two files (NFC-normalized) would collide.

Expected images directory layout

images/
  rarity.json            - optional rarity mapping (keys file basenames or subfolder names)
  avatar/                - parent folder (one token per image)
    bodyAcc/             - category: flat image files
    top/                 - category: may contain nested subfolders
      top1/              -   ...whose images are flattened into the category
  thumbnail/
    ...

Step-by-Step Workflow

Each command can be run individually, allowing you to verify results between steps. All intermediate files are saved to ./output/.

Step 1: Upload Images

npm run upload-images
  • Reads: Image files from IMAGES_DIR (default ./images)
  • Produces: ./output/grouped-upload-results.json — one item per image with its Swarm ref and gateway url
  • Verify: Open a few url values from the JSON in a browser. Pin status can be checked with curl $SWARM_BEE_API_URL/pins/<ref> (200 = pinned).

Step 2: Generate Metadata

npm run generate-metadata
  • Reads: ./output/grouped-upload-results.json (and images/rarity.json if present)
  • Produces: ./output/metadata/*.json and ./output/metadata-results.json
  • Verify: Open the JSON files in ./output/metadata/ to confirm each token has correct name, description, and an image URL pointing to your Swarm gateway.

Step 3: Upload Metadata

npm run upload-metadata
  • Reads: ./output/metadata/ folder (uploaded as a single Swarm collection)

  • Produces: ./output/metadata-ref.txt

  • Verify: Fetch one token through the gateway — note that the bare collection root (/bzz/<ref>/) returns 404 because the manifest has no index document; always append a file path:

    TOKEN=$(ls output/metadata | head -1 | sed 's/\.json$//')
    curl "$SWARM_GATEWAY_URL/bzz/$(cat output/metadata-ref.txt)/$TOKEN.json"

Step 4: Set Base URI

npm run set-base-uri
  • Reads: ./output/metadata-ref.txt (or pass --ref <ref>)
  • Produces: On-chain transaction setting baseURI on the contract
  • Verify: Confirm the transaction on a block explorer (Base Sepolia). The base URI should be ${SWARM_GATEWAY_URL}/bzz/<ref>/ with a trailing slash — the contract appends <tokenId>.json.

Step 5: Mint Tokens

npm run mint-tokens -- --to <wallet-address>
  • Reads: ./output/metadata-results.json, CLI flags (--to, optional --amount)
  • Produces: On-chain mint transaction(s)
  • Note: Token IDs are keccak256 hashes of "<parent>/<image basename>" (not sequential integers)
  • Verify: Check the recipient's token balance on the block explorer.

Step 6: Sync to Database

npm run sync-db
  • Reads: ./output/metadata-results.json
  • Produces: Records in the tb_nfts MySQL table (table is rebuilt on each sync)
  • Note: Merges avatar and thumbnail entries by name into a single row with bare Swarm references in thumbnail_ref / avatar_ref / avatar2_ref (avatar2_ref holds the 뒤_-prefixed back image of hair items). Orphans (avatar-only or thumbnail-only) are allowed with nullable columns. Consumers build public URLs as ${SWARM_GATEWAY_URL}/bzz/<ref>.
  • Verify: Query the database to confirm records were inserted correctly.

One-Shot Pipeline

To run all steps at once with confirmation prompts between steps:

npm run pipeline -- --to <wallet-address> --dir ./images

Adding to the Collection Later

The collection is designed to grow:

  1. Drop the new image files into images/ (unique basenames per parent folder!) and run upload-images — existing images re-resolve to their old references for free; only new content is uploaded.
  2. Run generate-metadata + upload-metadata — the full metadata folder is regenerated and re-uploaded, producing a new metadata reference.
  3. Run set-base-uri to re-point the contract at the new metadata reference (old tokens keep resolving — their <tokenId>.json files are included in the new folder).
  4. Mint the new tokens and sync-db.

Environment Variables

See .env.example for all required variables:

Variable Description
SWARM_BEE_API_URL Bee node HTTP API (e.g. http://localhost:1633) — used for uploads
SWARM_STAMP_BATCH_ID Postage stamp batch ID used to stamp uploads
SWARM_GATEWAY_URL Swarm API Gateway you would like the public to use to read your uploaded data. Default: public gateway
RPC_URL Blockchain RPC endpoint
PRIVATE_KEY Wallet private key for contract transactions
CONTRACT_ADDRESS Deployed OpenRun contract address
DB_HOST MySQL host
DB_PORT MySQL port
DB_USER MySQL user
DB_PASSWORD MySQL password
DB_NAME MySQL database name
METADATA_BASE_NAME Default NFT name prefix
METADATA_BASE_DESCRIPTION Default NFT description
IMAGES_DIR Source images directory

Project Structure

src/
  config/index.ts       - Environment configuration
  types/index.ts        - TypeScript interfaces
  services/
    swarmService.ts     - Swarm upload via bee-js (per-image + metadata collection)
    metadataService.ts  - ERC-1155 metadata JSON generation
    contractService.ts  - OpenRun contract interaction (ethers.js)
    dbService.ts        - MySQL tb_nfts CRUD operations
  utils/
    swarmUrl.ts         - Build gateway URLs (bzz) for image refs and baseURI
    mergeRecords.ts     - Merge avatar/thumbnail metadata into NFT records
    rarityIndex.ts      - Resolve rarity from images/rarity.json
    confirm.ts          - Interactive yes/no prompt for pipeline steps
  commands/
    uploadImages.ts     - CLI: upload images
    generateMetadata.ts - CLI: generate metadata JSONs
    uploadMetadata.ts   - CLI: upload metadata folder to Swarm
    setBaseUri.ts       - CLI: set contract baseURI
    mintTokens.ts       - CLI: mint tokens
    syncDb.ts           - CLI: sync to database
    pipeline.ts         - CLI: full end-to-end pipeline
  index.ts              - Main CLI entry point

Related

  • Contract repo: openrun-contract (Foundry, Solidity)
  • Contract: OpenRun ERC-1155 on Base Sepolia

About

CLI toolset for mass-uploading images to Swarm, generating ERC-1155 metadata, minting NFTs on the OpenRun contract, and syncing NFT data to MySQL

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages