npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mint-nft-plugin

v1.0.16

Published

Plugin for mint nft in API City

Readme

API City Plugin Setup Guide

This guide outlines the requirements and best practices for creating a plugin for API City.

Quick Start Example

Here's a minimal working plugin example:

import { BasePlugin, PluginContext } from "api-city-sdk";

class HelloPlugin extends BasePlugin {
  constructor() {
    super({
      name: "Hello Plugin",
      description: "A simple hello world plugin",
      version: "1.0.0",
      author: "Your Name",
      permissions: [],
      entryPoints: {
        main: "hello"  // This must match your base command
      }
    });
  }

  async initialize(context: PluginContext): Promise<void> {
    // Store context for later use
    this.context = context;
  }

  async handleCommand(command: string, args: string[]): Promise<void> {
    if (command !== "hello") {
      this.emit("message", { content: "Unknown command" });
      return;
    }

    const name = args[0] || "World";
    this.emit("message", { content: `Hello, ${name}!` });
  }

  getCommands(): { command: string; description: string; usage: string }[] {
    return [
      {
        command: "hello",              // Must match entryPoints.main
        description: "Say hello",
        usage: "/hello [name]"         // Always prefix with /
      }
    ];
  }
}

export = HelloPlugin;  // Must use this exact syntax

Core Requirements

1. Plugin Class Structure

import { BasePlugin, PluginContext } from "api-city-sdk";

class YourPlugin extends BasePlugin {
  constructor() {
    super({
      name: "Plugin Name",
      description: "Plugin Description",
      version: "1.0.0",
      author: "Author Name",
      permissions: [],
      entryPoints: {
        main: "commandName"
      }
    });
  }

  async initialize(context: PluginContext): Promise<void> {
    // Initialize your plugin
  }

  async handleCommand(command: string, args: string[]): Promise<void> {
    // Handle commands
  }

  getCommands(): { command: string; description: string; usage: string }[] {
    return [
      {
        command: "commandName",           // Base command without slash
        description: "Command description",
        usage: "/commandName <params>"    // Usage with slash
      }
    ];
  }
}

export = YourPlugin;  // Must use CommonJS export

2. Package Configuration

Create a package.json with:

{
  "name": "your-plugin-name",
  "version": "1.0.0",
  "type": "module",
  "main": "dist/index.cjs",
  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "require": "./dist/index.cjs",
      "import": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  }
}

3. Build Configuration

Create a build.js with:

import * as esbuild from "esbuild";

const sharedConfig = {
  entryPoints: ["src/index.ts"],
  bundle: true,
  minify: true,
  target: "es2020",
  platform: "node",
  sourcemap: true,
  treeShaking: true,
  external: [
    "@solana/web3.js",
    "@metaplex-foundation/umi",
    "@metaplex-foundation/umi-bundle-defaults",
    "@metaplex-foundation/mpl-core",
    "api-city-sdk"
  ]
};

await esbuild.build({
  ...sharedConfig,
  format: "esm",
  outfile: "dist/index.js",
});

await esbuild.build({
  ...sharedConfig,
  format: "cjs",
  outfile: "dist/index.cjs",
});

Command Handling Best Practices

  1. Command Validation
    async handleCommand(command: string, args: string[]): Promise<void> {
      // Always validate the base command first
      if (command !== "yourcommand") {
        this.emit("message", { content: "Unknown command" });
        return;
      }
    
      // Handle subcommands with a switch statement
      const subCommand = args[0] || "help";
      switch (subCommand) {
        case "help":
          this.emit("message", {
            content: `Available commands:
  • /yourcommand help: Show this help message

  • /yourcommand action : Do something` }); break;

     case "action":
       // Validate parameters
       if (args.length < 2) {
         this.emit("message", { content: "Missing parameters" });
         return;
       }
       // Handle the action
       break;
    
     default:
       this.emit("message", { content: "Unknown subcommand" });

    } }

  1. User Feedback
    // Success messages
    this.emit("message", { content: "Operation successful!" });
       
    // Error handling
    try {
      // Your code
    } catch (err: any) {
      console.error("Error:", err);
      this.emit("message", { content: `Error: ${err.message}` });
    }

Project Structure

your-plugin/
├── src/
│   └── index.ts         # Main plugin implementation
├── build.js            # Build configuration
├── package.json        # Package configuration
├── tsconfig.json       # TypeScript configuration
└── README.md          # Documentation

Testing Your Plugin

  1. Local Testing

    // test.js
    import YourPlugin from './dist/index.js';
       
    const plugin = new YourPlugin();
       
    // Mock the context
    const mockContext = {
      wallet: {
        publicKey: null,
        signTransaction: async (tx) => tx,
        connected: false
      }
    };
       
    // Test your commands
    async function test() {
      await plugin.initialize(mockContext);
      await plugin.handleCommand('yourcommand', ['help']);
    }
       
    // Mock the emit method
    YourPlugin.prototype.emit = (event, data) => {
      console.log(`[${event}] ${data.content}`);
    };
       
    test().catch(console.error);
  2. Run Tests

    npm run build
    node test.js

Important Guidelines

  1. Export Syntax

    • Use export = PluginClass (CommonJS style)
    • Don't mix named exports with module exports
    • Don't use export default
  2. Command Structure

    • Use static strings for commands, not class properties
    • Include proper command descriptions and usage strings
    • Always prefix usage examples with "/" but not the command itself
  3. Build Requirements

    • Build both ESM and CommonJS versions
    • Mark all SDK dependencies as external
    • Use Node.js platform in build config
  4. Plugin Service Integration

    • Implement all required BasePlugin methods
    • Properly handle command parsing and execution
    • Use the emit method for user feedback

Development Workflow

  1. Setup

    npm init
    npm install api-city-sdk @types/node typescript esbuild --save-dev
  2. Build

    npm run build
  3. Publish

    npm version patch
    npm publish
  4. Submit

    • Submit your plugin through the API City plugin submission interface
    • Ensure all commands are properly defined and documented
    • Test your plugin thoroughly before submission

Common Issues

  1. No Commands Found Error

    • Check if getCommands() returns the correct format
    • Verify export syntax is CommonJS style
    • Ensure build configuration is correct
  2. Build Errors

    • Make sure all dependencies are properly marked as external
    • Verify package.json has correct "type" and "exports" fields
    • Check for proper TypeScript configuration

Dependencies

Required peer dependencies:

{
  "api-city-sdk": "latest"
}

License

ISC

Browser Compatibility

Your plugin must work in both Node.js and browser environments since it will be loaded via CDN in the frontend. Ensure:

  1. Build Configuration

    // ESM build for browsers
    await esbuild.build({
      ...sharedConfig,
      format: "esm",
      platform: "browser",  // Important for CDN loading
      outfile: "dist/index.js",
    });
  2. Package Configuration

    {
      "browser": "dist/index.js",
      "exports": {
        ".": {
          "browser": "./dist/index.js",
          "require": "./dist/index.cjs",
          "import": "./dist/index.js"
        }
      }
    }
  3. Browser-Safe Code

    • Don't use Node.js-specific APIs (fs, path, etc.)
    • Handle browser-specific cases in your plugin
    • Test your plugin in both Node.js and browser environments