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

@kigo-dev/marketplace-sdk

v0.5.0

Published

SDK for integrating mini-apps into the Kigo marketplace ecosystem

Readme

@kigo-dev/marketplace-sdk

SDK for integrating mini-apps into the Kigo marketplace ecosystem.

npm version License: MIT

Leer en Español


The Kigo Marketplace SDK allows web developers to integrate their applications ("mini-apps") within the Kigo native ecosystem. It provides access to native capabilities such as Payments, Authentication, Navigation, Location, and UI through a secure bridge between JavaScript and the Kigo Native App.

Table of Contents

Installation

npm install @kigo-dev/marketplace-sdk

Quick Start

Step 1: Initialization

The SDK must be initialized before using any module. This ensures the communication bridge with the native app is ready.

import { kigo } from '@kigo-dev/marketplace-sdk';

async function startApp() {
  try {
    // 1. Initialize the bridge
    await kigo.init();

    // 2. Get user session and context
    const session = await kigo.auth.init();
    console.log(`Authenticated user: ${session.userId}`);
  } catch (error) {
    console.error('Error initializing Kigo SDK:', error);
    // Handle the case where the app is not running inside Kigo
  }
}

startApp();

Bridge Configuration

kigo.init() accepts optional configuration to customize the bridge behavior:

await kigo.init({
  timeout: 15000,          // Default timeout for bridge calls (ms). Default: 10000
  enableLogging: false,    // Disable bridge debug logs in production
  devtools: { enabled: true }, // Enable built-in DevTools console
});

Note: Specific modules like payments.checkout() and navigation.openExternal() use their own extended timeouts to account for user interaction, regardless of the global setting.

Step 2: Local Development (Playground)

The SDK does not work in a standard browser because it requires the native bridge.

To develop locally, use the Playground included in the repository, which simulates the native app's behavior:

# Install dependencies
npm install

# Start dev server with playground
npm run dev

Note: If you see the error Bridge not available, make sure your app is running inside the Kigo container or using the appropriate test environment.

Modules Reference

Auth (Authentication)

Manages the user session. The mini-app should never ask the user to log in; it inherits the session from Kigo.

kigo.auth.init()

Performs the handshake and retrieves the session token.

Returns:

{
  sessionId: string;  // Ephemeral token for backend calls
  userId: string;     // User's ID in Kigo
  expiresAt: number;  // Expiration timestamp
}

Payments

Opens the native payment interface. The web app never handles credit card details directly.

Timeout: checkout() uses a 5-minute timeout (instead of the default 10 seconds) because the user interacts with the native payment UI. getStatus() uses the standard timeout.

kigo.payments.checkout(payload)

Initiates the native payment flow.

Parameters:

{
  amount: number;        // Amount to charge (e.g. 100.00)
  currency: string;      // Currency code (e.g. 'MXN')
  description?: string;  // Concept displayed to the user
  metadata?: object;     // Extra data for your backend
}

Returns:

{
  transactionId: string;
  status: 'approved' | 'rejected' | 'pending';
  amount: number;
  currency: string;
  createdAt: number;
}

Common Errors:

| Error Code | Description | |---|---| | INSUFFICIENT_FUNDS | User has insufficient balance or card was declined | | PAYMENT_CANCELLED | User closed the payment modal | | PAYMENT_FAILED | Payment processing error | | INVALID_AMOUNT | Invalid amount (negative or zero) |

kigo.payments.getStatus(payload)

Checks the status of an existing transaction.

Parameters:

{
  transactionId: string;
}

Returns:

{
  transactionId: string;
  status: 'approved' | 'pending' | 'rejected' | 'cancelled';
  updatedAt: number;
}

Navigation

Controls the mini-app lifecycle.

kigo.navigation.close()

Closes the mini-app and returns the user to the Kigo Marketplace.

// Simple close
await kigo.navigation.close();

// Close with reason (useful for analytics)
await kigo.navigation.close({ reason: 'Purchase completed' });

kigo.navigation.openExternal(options)

Opens a URL in the system browser or in a controlled in-app browser.

Parameters:

{
  url: string;              // URL to open (must be http:// or https://)
  openInBrowser?: boolean;  // true = system browser, false = in-app browser (default: false)
  waitForClose?: boolean;   // true = promise resolves when the in-app browser is dismissed (default: false)
  closeOnUrls?: string[];   // URLs that auto-close the browser when navigated to
}

Returns: { matchedUrl?: string } — the URL that triggered the auto-close (from closeOnUrls), or undefined if the user closed manually.

Basic usage:

// Open in external browser (Chrome/Safari)
await kigo.navigation.openExternal({
  url: 'https://example.com/terms',
  openInBrowser: true,
});

// Open in in-app browser
await kigo.navigation.openExternal({
  url: 'https://example.com/privacy',
  openInBrowser: false,
});

Wait for the user to return:

// Open a page and wait until the user closes the in-app browser
await kigo.navigation.openExternal({
  url: 'https://example.com/info',
  openInBrowser: false,
  waitForClose: true,
});
// This line runs only after the in-app browser is dismissed
console.log('User returned to the mini-app');

Third-party payment flow with closeOnUrls:

When integrating with external payment providers (e.g., Orkesta), use closeOnUrls to detect when the payment finishes. The native app intercepts the redirect before the target page loads, auto-closes the browser, and returns the matched URL to your mini-app.

const result = await kigo.navigation.openExternal({
  url: 'https://payment-provider.com/pay?ref=12345',
  openInBrowser: false,
  waitForClose: true,
  closeOnUrls: [
    'https://mysite.com/payment/success',
    'https://mysite.com/payment/failure',
  ],
});

if (result.matchedUrl?.includes('/success')) {
  await kigo.ui.toast({ message: 'Payment successful!', type: 'success' });
} else if (result.matchedUrl?.includes('/failure')) {
  await kigo.ui.toast({ message: 'Payment failed', type: 'error' });
} else {
  // User closed the browser manually without completing
}

Common Errors:

| Error Code | Description | |---|---| | INVALID_URL | URL is malformed or uses a non-http(s) scheme | | NAVIGATION_BLOCKED | URL is not in the backend allowlist |


UI (User Interface)

Uses native components to maintain visual consistency with the Kigo app.

kigo.ui.toast({ message, type?, duration? })

Shows a native floating notification.

  • type: 'success' | 'error' | 'info' | 'warning' (default: 'info')
  • duration: Duration in milliseconds (default: 3000)
await kigo.ui.toast({
  message: 'Item added to cart',
  type: 'success',
});

kigo.ui.confirm({ title, message, confirmText?, cancelText?, type? })

Shows a native confirmation dialog (OK/Cancel).

Returns: { confirmed: boolean }

const result = await kigo.ui.confirm({
  title: 'Cancel order',
  message: 'This action cannot be undone.',
  confirmText: 'Yes, cancel',
  cancelText: 'Keep order',
  type: 'destructive',
});

if (result.confirmed) {
  // Proceed with cancellation
}

kigo.ui.setTitle(title)

Changes the text in the app's top navigation bar.

await kigo.ui.setTitle('Product Detail');

Device

Retrieves environment information to adapt your layout and behavior.

kigo.device.getContext()

Returns:

{
  theme: 'light' | 'dark';          // Useful for dynamic CSS
  locale: string;                    // e.g. 'es', 'en'
  platform: 'ios' | 'android';
  safeArea: {
    top: number;
    bottom: number;
    left: number;
    right: number;
  };
  appVersion: string;
  projectRef?: string;               // Current project reference
  screen: {
    width: number;
    height: number;
  };
}
const context = await kigo.device.getContext();

// Apply safe area padding
document.body.style.paddingTop = `${context.safeArea.top}px`;

// Theme adaptation
if (context.theme === 'dark') {
  document.body.classList.add('dark-mode');
}

Location

Retrieves the user's geographic coordinates from the native app. The web service never accesses GPS hardware directly — it always goes through the native bridge.

kigo.location.getCurrent()

Requests the device's current location.

Returns:

{
  latitude: number;    // Decimal degrees (e.g. 19.4326)
  longitude: number;   // Decimal degrees (e.g. -99.1332)
  accuracy?: number;   // Accuracy in meters (optional)
}
const loc = await kigo.location.getCurrent();
console.log(`User is at ${loc.latitude}, ${loc.longitude}`);

// Use for nearby searches
const stores = await fetchNearbyStores(loc.latitude, loc.longitude);

Common Errors:

| Error Code | Description | |---|---| | LOCATION_UNAVAILABLE | Location services are disabled or permission was denied |


Storage

Securely stores persistent data, isolated per mini-app.

kigo.storage.set(key, value)

Saves a string value.

kigo.storage.get(key)

Reads a string value. Returns { value: string | null }.

kigo.storage.remove(key)

Deletes a stored value.

kigo.storage.setObject(key, obj)

Saves a JSON object (automatic serialization).

kigo.storage.getObject<T>(key)

Reads and parses a JSON object. Returns T | null.

// Save preferences
await kigo.storage.setObject('user_prefs', {
  theme: 'dark',
  notifications: true,
});

// Read preferences
const prefs = await kigo.storage.getObject('user_prefs');

Analytics

Sends tracking events to the Kigo analytics pipeline.

kigo.analytics.track({ event, properties? })

await kigo.analytics.track({
  event: 'purchase_completed',
  properties: {
    amount: 100,
    currency: 'MXN',
    product_id: 'prod_123',
  },
});

Use snake_case for event names. Be specific but concise.


DevTools

Built-in debug console for inspecting bridge traffic, API calls, and SDK lifecycle events in real time. Designed for development and QA — it renders inside a Shadow DOM so it never interferes with your application's styles or layout.

Enabling DevTools

// Option A: Enable programmatically (recommended)
kigo.devtools.enable();

// Option B: Enable via init()
await kigo.init({
  devtools: { enabled: true },
});

Enabling with fetch interception

kigo.devtools.enable({
  interceptFetch: true,
  fetchFilter: url => url.includes('/v1/'),
});

When interceptFetch is true, DevTools hooks window.fetch to log API calls with method, path, status code, and duration. Use fetchFilter to limit which URLs are captured.

Configuration

| Option | Type | Default | Description | |---|---|---|---| | enabled | boolean | false | Auto-enable on kigo.init() | | interceptFetch | boolean | false | Log fetch() calls in the console | | fetchFilter | (url: string) => boolean | — | Only log fetch URLs that pass this filter | | maxEntries | number | 200 | Maximum log entries to retain | | panelHeight | string | '40vh' | Panel height (any CSS value) | | shortcutKey | string | 'D' | Keyboard shortcut key (Ctrl+Shift+key) |

API

kigo.devtools.enable(config?)   // Activate the overlay
kigo.devtools.disable()         // Tear down and restore globals
kigo.devtools.toggle()          // Open/close panel (or press Ctrl+Shift+D)
kigo.devtools.clear()           // Remove all log entries
kigo.devtools.copyLogs()        // Copy visible entries to clipboard
kigo.devtools.isEnabled()       // Check if active

// Push custom entries
kigo.devtools.log('Bootstrap complete');
kigo.devtools.log('error', 'Auth failed', JSON.stringify(err));

What it captures

| Entry type | Badge | Source | |---|---|---| | Bridge request | JS → Flutter | Every bridge.send() call with service, action, and payload | | Bridge response | Flutter → JS | Every response, showing service.action and round-trip time | | Bridge timeout | ERROR | Requests that exceeded the configured timeout | | API success | API | Fetch calls returning 2xx (when interceptFetch is on) | | API error | API ERR | Fetch calls returning non-2xx or network errors | | SDK lifecycle | INFO | Bridge ready, initialization, internal Bridge logs |

Safety

DevTools is wrapped in error boundaries at every layer. It will never crash your application, even if its own internals fail. When disabled, window.fetch is fully restored to its original reference.


Error Handling

The SDK uses Promises. Always use try/catch. Errors follow this structure:

interface BridgeError {
  code: string;     // Standard error code
  message: string;  // Human-readable message for debugging
}

Error Codes

| Code | Description | Recommended Action | |---|---|---| | BRIDGE_TIMEOUT | The native app took too long to respond | Retry or show a network error | | AUTH_FAILED | Could not obtain a session | Show error screen with an "Exit" button | | PAYMENT_CANCELLED | User closed the checkout | Do nothing, or ask if they want to retry | | CHANNEL_NOT_AVAILABLE | App is not running inside Kigo | Only use within the Kigo environment | | SESSION_EXPIRED | User session has expired | Re-initialize with kigo.auth.init() | | LOCATION_UNAVAILABLE | Location services disabled or permission denied | Ask the user to enable location |

Best Practices

Environment Validation

Call kigo.init() as early as possible in your application (e.g., in App.tsx or main.ts). If it fails, show a friendly screen indicating the app must be opened from Kigo.

// main.ts
try {
  await kigo.init();
} catch {
  showKigoRequiredScreen();
}

Safe Areas

Use kigo.device.getContext() to get safeArea.top and safeArea.bottom. Apply that padding to your main container to prevent content from being hidden behind the status bar or home indicator on iOS.

const { safeArea } = await kigo.device.getContext();
document.documentElement.style.setProperty('--safe-top', `${safeArea.top}px`);
document.documentElement.style.setProperty('--safe-bottom', `${safeArea.bottom}px`);

No Tokens in URLs

Never pass tokens or user IDs via URL parameters. Always rely on kigo.auth.init() to securely obtain the user's identity.

Robust Payments

Even if the SDK returns approved, your backend should listen to Kigo Webhooks to confirm the transaction asynchronously (reconciliation).

FAQ

Q: Can I test the SDK in my Chrome/Safari browser? A: Not directly. The SDK requires the native bridge to be available. Use the Playground included in this repository for local development, which mocks the native bridge behavior.

Q: What happens if the user has no internet? A: Bridge calls (kigo.*) will fail with an error or timeout. Handle these cases gracefully in your UI.

Q: How do I know which user is using my app? A: Call kigo.auth.init(). It returns a userId and a sessionId that you can send to your own backend for request validation.

Q: Can I use the SDK outside the Kigo app? A: The SDK is designed to run inside the Kigo native app container. Attempting to use it outside will result in a CHANNEL_NOT_AVAILABLE error.

Development

# Install dependencies
npm install

# Development mode with playground
npm run dev

# Production-like dev mode
npm run dev:prod

# Build the SDK
npm run build

# Type checking
npm run typecheck

Architecture

src/
├── bridge/      # Core messaging system (JS ↔ Native)
├── modules/     # Business features (auth, payments, navigation, ...)
├── devtools/    # Built-in debug console (Shadow DOM, event bus)
├── utils/       # Shared utilities
└── index.ts     # Main entry point

License

MIT © Kigo 2026