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

@myazahq/pos-sdk

v1.0.7

Published

Production-grade crypto POS payment SDK — accepts any crypto token in React, Next.js, Vue, Svelte, or plain JS

Downloads

810

Readme

@myazahq/pos-sdk

Accept crypto payments in your storefront with a single method call — no webhooks, no Web3 setup required. Powered by Gridlog.


Install

npm install @myazahq/pos-sdk
# yarn add @myazahq/pos-sdk
# pnpm add @myazahq/pos-sdk

Works with React, Next.js, Vue, Svelte, Nuxt, Vite, and plain JavaScript.


How it works

new MyazaPOS()  →  sdk.init()  →  sdk.checkout()

That's the entire integration. init() fetches your merchant profile automatically (name, logo) and checkout() opens a built-in modal that handles network selection, displays a wallet address and QR code, and polls for payment status — all automatically. You just listen for events and fulfil the order.


Quick Start

import { MyazaPOS } from '@myazahq/pos-sdk';

const sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });

await sdk.init(); // fetches merchant profile + validates config

// Listen for the payment you care about
sdk.on('payment.confirmed', ({ session }) => {
  fulfillOrder(session.id);
});

// Open the full checkout UI — one line
await sdk.checkout({ amount: 5000, currency: 'NGN' });

SSR frameworks (Next.js, Nuxt): The SDK manipulates the DOM and must only run in the browser. Wrap it in useEffect (React) or onMounted (Vue) — see Framework Examples.


sdk.checkout() — Start here

checkout() is the primary method. Call it when your customer clicks "Pay". It handles the full payment flow end-to-end:

  1. Fetches supported networks in the background (the modal opens instantly while this loads).
  2. Shows a network & token selector modal, pre-filled with the amount and your merchant name.
  3. Once the customer confirms, transitions to the payment modal — wallet address, QR code, live countdown.
  4. Polls for payment status and fires events at every stage.
  5. Closes itself on success, failure, or cancellation.
// Minimal — shows the full network/token selector
await sdk.checkout({ amount: 5000, currency: 'NGN' });

// With bank payout — Gridlog sends fiat to this account after payment
await sdk.checkout({
  amount:              5000,
  currency:            'NGN',
  payoutAccountNumber: '0123456789',
  payoutNetworkId:     'bank-network-uuid',   // from sdk.getBanks()
});

Parameters

| Parameter | Type | Default | Description | |---|---|---|---| | amount | number | required | Fiat amount (e.g. 5000). | | currency | string | 'NGN' | Fiat currency code. | | payoutAccountNumber | string | — | Bank account for fiat payout after payment. | | payoutNetworkId | string | — | Bank network ID from getBanks(). Required when payoutAccountNumber is set. |

Returns null if the customer closes the modal without paying, or a PaymentSession object otherwise.


Payout to a bank account

To route the fiat payout to a specific bank account, look up the bank and verify the account number first:

// 1. List banks that support NGN payouts
const banks = await sdk.getBanks('NGN');
// → [{ id, name, networkId, currency, country, available }, ...]

// 2. Confirm the account holder before charging the customer
const account = await sdk.resolveAccount(banks[0].networkId, '0123456789');

if (!account.matched) {
  // Account not found — show an error to the user
  return;
}

console.log('Account holder:', account.accountName); // "John Doe"

// 3. Pass verified details into checkout
await sdk.checkout({
  amount:              5000,
  currency:            'NGN',
  payoutAccountNumber: account.accountNumber,
  payoutNetworkId:     account.networkId,
});

Both payoutAccountNumber and payoutNetworkId are optional, but they must be provided together — one without the other will be rejected.


Events

Register handlers with sdk.on() before calling checkout().

sdk.on('payment.created', ({ session }) => {
  // Payment session opened — address is ready
  console.log('Send', session.token, 'to', session.address);
});

sdk.on('payment.received', ({ sessionId }) => {
  // Crypto arrived — payout is processing
});

sdk.on('payment.confirmed', ({ session }) => {
  // Payout complete — safe to fulfil the order
  fulfillOrder(session.id);
});

sdk.on('payment.failed', ({ sessionId, reason }) => {
  console.error('Payment failed:', reason);
});

sdk.on('payment.expired', ({ sessionId }) => {
  // Session timed out — customer can try again
});

sdk.on('payment.cancelled', ({ sessionId }) => {
  // Customer closed the modal
});

Configuration

const sdk = new MyazaPOS({
  merchantId:        'YOUR_MERCHANT_ID',  // required
  isSandbox:         false,               // true → use Gridlog sandbox (testing only)
  pollIntervalMs:    5_000,               // how often to poll for status (default: 5 sec)
  maxPollDurationMs: 900_000,             // give up polling after this long (default: 15 min)

  theme: {
    primaryColor:    '#6366f1',           // buttons and highlights
    backgroundColor: '#ffffff',           // modal background
    textColor:       '#1a1a2e',           // all text
    borderRadius:    12,                  // corner radius in px
    fontFamily:      'Inter, sans-serif',
    logoUrl:         'https://your-site.com/logo.png',  // must be HTTPS
    colorScheme:     'light',             // 'light' | 'dark' | 'system'
    customCss:       '.myaza-cancel-btn { display: none; }',
  },
});

Merchant name: You do not need to configure your store name. The SDK fetches it automatically from your Gridlog merchant profile during init() and displays it in the checkout modal header.

For advanced config (fraud rules, plugins, multi-tenant, observability) see MAINTAINERS.md.


Sandbox vs Production

// Sandbox — safe for development and testing
const sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID', isSandbox: true });

// Production — the default
const sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });

| | API base URL | Config | |---|---|---| | Production | https://secureapi.gridlog.io/api/v1 | isSandbox: false (default) | | Sandbox | https://sandbox.secureapi.gridlog.io/api/v1 | isSandbox: true | | Custom | Your own URL | apiBaseUrl: 'https://...' |

apiBaseUrl takes precedence over isSandbox when both are set.

When isSandbox: true, the SDK logs a warning immediately at construction time so you cannot accidentally ship a sandbox config to production.


Framework Examples

React

import { useEffect, useRef } from 'react';
import { MyazaPOS } from '@myazahq/pos-sdk';

export function PayButton({ amount }: { amount: number }) {
  const sdkRef = useRef<MyazaPOS | null>(null);

  useEffect(() => {
    const sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });
    sdk.init().then(() => { sdkRef.current = sdk; });
    sdk.on('payment.confirmed', ({ session }) => fulfillOrder(session.id));
    return () => { void sdk.terminate(); };
  }, []);

  return (
    <button onClick={() => sdkRef.current?.checkout({ amount, currency: 'NGN' })}>
      Pay with Crypto
    </button>
  );
}

Next.js (App Router)

'use client';

import { useEffect, useRef } from 'react';
import { MyazaPOS } from '@myazahq/pos-sdk';

export function PayButton({ amount }: { amount: number }) {
  const sdkRef = useRef<MyazaPOS | null>(null);

  useEffect(() => {
    const sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });
    sdk.init().then(() => { sdkRef.current = sdk; });
    return () => { void sdk.terminate(); };
  }, []);

  return (
    <button onClick={() => sdkRef.current?.checkout({ amount, currency: 'NGN' })}>
      Pay with Crypto
    </button>
  );
}

For Next.js Pages Router or anywhere you need lazy loading:

const { MyazaPOS } = await import('@myazahq/pos-sdk');

Vue 3

<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import { MyazaPOS } from '@myazahq/pos-sdk';

const props = defineProps<{ amount: number }>();
let sdk: MyazaPOS | null = null;

onMounted(async () => {
  sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });
  await sdk.init();
  sdk.on('payment.confirmed', ({ session }) => fulfillOrder(session.id));
});

onUnmounted(() => { sdk?.terminate(); });
</script>

<template>
  <button @click="sdk?.checkout({ amount: props.amount, currency: 'NGN' })">
    Pay with Crypto
  </button>
</template>

Nuxt 3

<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import type { MyazaPOS as TSDK } from '@myazahq/pos-sdk';

let sdk: TSDK | null = null;

onMounted(async () => {
  const { MyazaPOS } = await import('@myazahq/pos-sdk');
  sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });
  await sdk.init();
});

onUnmounted(() => { sdk?.terminate(); });
</script>

Svelte / SvelteKit

<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import type { MyazaPOS as TSDK } from '@myazahq/pos-sdk';

  export let amount: number;
  let sdk: TSDK | null = null;

  onMount(async () => {
    const { MyazaPOS } = await import('@myazahq/pos-sdk');
    sdk = new MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });
    await sdk.init();
  });

  onDestroy(() => { sdk?.terminate(); });
</script>

<button on:click={() => sdk?.checkout({ amount, currency: 'NGN' })}>
  Pay with Crypto
</button>

CDN (no build step)

<script src="https://cdn.jsdelivr.net/npm/@myazahq/pos-sdk/dist/index.umd.js"></script>
<script>
  const sdk = new MyazaPOS.MyazaPOS({ merchantId: 'YOUR_MERCHANT_ID' });

  sdk.init().then(() => {
    document.getElementById('pay-btn').addEventListener('click', () => {
      sdk.checkout({ amount: 5000, currency: 'NGN' });
    });

    sdk.on('payment.confirmed', ({ session }) => {
      window.location.href = '/order-complete?id=' + session.id;
    });
  });
</script>

Server-Side Verification

Always verify payment status from your server before fulfilling an order. Never trust client-side events alone.

// Your backend — keep the Bearer token server-side only
const res = await fetch(`https://secureapi.gridlog.io/api/v1/sdk/pos/sessions/${sessionId}?merchantId=<merchantId>`, 

const data = await res.json();

if (data.data.status === 'paid_out') {
  await fulfillOrder(data.data.id);
}

Store your Bearer token in a secret manager (e.g. AWS Secrets Manager, Doppler) — never expose it in client-side code or commit it to source control.


All SDK Methods

| Method | Returns | Description | |---|---|---| | sdk.init() | Promise<this> | Initialise the SDK. Fetches merchant profile. Call once before anything else. | | sdk.checkout(params) | Promise<PaymentSession \| null> | Start here. Opens the full checkout UI. | | sdk.createSession(params) | Promise<PaymentSession> | Low-level. Opens the payment modal directly when you already know the chain and token. Requires chain and token. | | sdk.getBanks(currency) | Promise<Bank[]> | List banks available for fiat payout (e.g. 'NGN'). | | sdk.resolveAccount(networkId, accountNumber) | Promise<BankAccountResolution> | Confirm an account holder name before charging. | | sdk.getNetworks() | Promise<SupportedNetwork[]> | List supported blockchains and tokens. | | sdk.getExchangeRate(currency, coin) | Promise<ExchangeRate> | Current exchange rate for a currency/token pair. | | sdk.on(event, handler) | this | Subscribe to an SDK event. | | sdk.once(event, handler) | this | Subscribe once — unsubscribes automatically after firing. | | sdk.off(event, handler) | this | Unsubscribe. | | sdk.use(plugin) | this | Register a plugin at runtime. | | sdk.registerMerchant(config) | this | Register a merchant for multi-tenant operation. | | sdk.getState() | SDKState | Current state machine state. | | sdk.terminate() | Promise<void> | Clean shutdown — cancels session, closes modal, uninstalls plugins. |


Maintainers

Architecture details, plugin authoring, fraud config, multi-tenant setup, CI/CD, and build instructions: MAINTAINERS.md.


Licence

MIT © Myaza