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

@gaian-network/sdk

v0.1.0

Published

TypeScript SDK for the Gaian Network API — cross-border crypto-to-fiat payments

Readme

@gaian-network/sdk

TypeScript SDK for the Gaian Network API — cross-border crypto-to-fiat payments.

Features

  • Full TypeScript types for all requests and responses
  • Two payment flows: standard (on-chain signing) and prefunded (no signing required)
  • KYC verification link generation and direct submission
  • QR code parsing for VN / PH / BR payment QRs
  • Exchange rate calculation
  • Tenant balance and policy checks
  • Zero runtime dependencies — uses native fetch (Node ≥ 18)

Installation

npm install @gaian-network/sdk

Quick start

import { GaianClient } from '@gaian-network/sdk';

const client = new GaianClient({
  apiKey: process.env.GAIAN_API_KEY!,
  environment: 'sandbox', // or 'production'
});

Get your API key at client-admin.gaian.network.


API reference

new GaianClient(options)

| Option | Type | Required | Default | |--------|------|----------|---------| | apiKey | string | Yes | — | | environment | 'sandbox' \| 'production' | No | 'sandbox' | | baseUrls.user | string | No | env default | | baseUrls.payment | string | No | env default | | timeoutMs | number | No | 30000 |


client.users

register(params)

Register a new user. Returns the existing user if the wallet address is already registered.

const { user } = await client.users.register({
  walletAddress: 'So11111111111111111111111111111111111111112',
});
// user.id, user.walletAddress, user.createdAt

getById(id)

const { data: user } = await client.users.getById(123);
// user.kycStatus, user.firstName, user.kyc.markets, ...

getByWallet(walletAddress)

const { data: user } = await client.users.getByWallet('So111...');

getMarkets(walletAddress)

Get per-market KYC approval status.

const { data } = await client.users.getMarkets('So111...');
// data.markets.VN.status, data.markets.PH.status, ...

getOrdersByIdentifier(identifier, params?)

Paginated order history by user ID or email.

const { data } = await client.users.getOrdersByIdentifier('[email protected]', {
  page: 1,
  limit: 20,
  status: 'completed',
});
// data.orders.items, data.orders.pagination

getOrdersByWallet(walletAddress, params?)

const { data } = await client.users.getOrdersByWallet('So111...', { page: 1 });

client.kyc

generateLink(params)

Generate a time-limited KYC verification link (Sumsub). Redirect the user to websdkUrl.

const { websdkUrl } = await client.kyc.generateLink({
  walletAddress: 'So111...',
});
window.location.href = websdkUrl; // redirect user

Do not cache websdkUrl — generate a fresh link each time.

submit(params)

Submit KYC data directly when you have already collected identity documents.

const result = await client.kyc.submit({
  userWalletAddress: 'So111...',
  userEmail: '[email protected]',
  firstName: 'Nguyen',
  lastName: 'Van A',
  dateOfBirth: '1990-01-15',
  gender: 'male',
  nationality: 'VN',
  type: 'ID_CARD',
  nationalId: '012345678901',
  issueDate: '2015-01-01',
  expiryDate: '2025-01-01',
  addressLine1: '123 Le Loi',
  addressLine2: 'Quan 1',
  city: 'Ho Chi Minh',
  state: 'Ho Chi Minh',
  zipCode: '700000',
  // base64 data URLs: data:image/jpeg;base64,...
  frontIdImage: 'data:image/jpeg;base64,...',
  backIdImage: 'data:image/jpeg;base64,...',
  holdIdImage: 'data:image/jpeg;base64,...',
  phoneNumber: '0901234567',
  phoneCountryCode: '+84',
});

Max request body size is 10 MB. Supported image formats: jpeg, png, gif, webp.


client.payments

placeOrder(params) — Standard flow

Place an order using an on-chain transaction.

const order = await client.payments.placeOrder({
  qrString: '00020101021238570010A0000007...',
  amount: 500000,          // fiat amount (VND)
  cryptoCurrency: 'USDC',
  fromAddress: 'So111...',
  chain: 'Solana',         // optional, defaults to Solana
  fiatCurrency: 'VND',     // optional, auto-detected from QR
});
// order.orderId, order.cryptoTransferInfo, order.cryptoAmount

After calling placeOrder, use order.cryptoTransferInfo to build and sign a legacy Solana transaction (not VersionedTransaction), then call verifyOrder.

placeOrderPrefund(params) — Prefunded flow

Deduct from tenant's pre-loaded balance. No on-chain signing required.

const order = await client.payments.placeOrderPrefund({
  qrString: '00020101021238570010A0000007...',
  amount: 500000,
  cryptoCurrency: 'USDC',
  fromAddress: 'So111...',
});
// proceed directly to polling

verifyOrder(params)

Submit the transaction hash after broadcasting the on-chain transaction.

const result = await client.payments.verifyOrder({
  orderId: order.orderId,
  transactionProof: 'txSignatureOrHash...', // 66–100 chars
});
// result.status: 'verified' | 'failed' | 'pending'
// result.bankTransferStatus: 'queued' | 'failed'

getOrderStatus(orderId)

Poll until status is 'completed' or 'failed'.

const status = await client.payments.getOrderStatus(order.orderId);
// status.status, status.fiatAmount, status.transactionHash, ...

client.exchange

calculate(params)

Get the crypto equivalent for a fiat amount before placing an order.

const { exchangeInfo } = await client.exchange.calculate({
  amount: 500000,
  country: 'VN',
  chain: 'Solana',
  token: 'USDC',
});
// exchangeInfo.cryptoAmount, exchangeInfo.exchangeRate, exchangeInfo.feeAmount

client.qr

parse(params)

Parse a merchant QR string and extract payment details.

const { qrInfo } = await client.qr.parse({
  qrString: '00020101021238570010A0000007...',
  country: 'VN', // optional hint
});
// qrInfo.isValid, qrInfo.bankBin, qrInfo.accountNumber, qrInfo.beneficiaryName

client.tenant

getBalance(currency?)

const balance = await client.tenant.getBalance('USDC');
// balance.availableBalance, balance.walletAddress, balance.chain

getTotalSpent()

const { totalSpent, limit } = await client.tenant.getTotalSpent();

checkPolicy(params)

Check if a wallet is allowed to transact in a given country.

const policy = await client.tenant.checkPolicy({
  walletAddress: 'So111...',
  countryCode: 'VN',
});
// policy.isAllowed, policy.tier ('KYC' | 'NON_KYC'), policy.limits.perTransaction

Payment flows

Standard payment (end-to-end)

import { GaianClient, GaianError } from '@gaian-network/sdk';

const client = new GaianClient({ apiKey: process.env.GAIAN_API_KEY! });

async function pay(walletAddress: string, qrString: string) {
  // 1. Check KYC
  const policy = await client.tenant.checkPolicy({ walletAddress, countryCode: 'VN' });
  if (!policy.isAllowed) throw new Error(policy.reason ?? 'Payment not allowed');

  // 2. Place order
  const order = await client.payments.placeOrder({
    qrString,
    amount: 500_000,
    cryptoCurrency: 'USDC',
    fromAddress: walletAddress,
    chain: 'Solana',
  });

  // 3. Build + sign + broadcast transaction using order.cryptoTransferInfo
  const txSignature = await signAndSendTransaction(order.cryptoTransferInfo);

  // 4. Verify
  await client.payments.verifyOrder({
    orderId: order.orderId,
    transactionProof: txSignature,
  });

  // 5. Poll until complete
  return pollOrderStatus(client, order.orderId);
}

async function pollOrderStatus(client: GaianClient, orderId: string) {
  while (true) {
    const status = await client.payments.getOrderStatus(orderId);
    if (status.status === 'completed' || status.status === 'failed') return status;
    await new Promise(r => setTimeout(r, 3_000));
  }
}

Prefunded payment

const order = await client.payments.placeOrderPrefund({
  qrString,
  amount: 500_000,
  cryptoCurrency: 'USDC',
  fromAddress: walletAddress,
});
// No verifyOrder needed — go straight to polling
const final = await pollOrderStatus(client, order.orderId);

KYC flow

// Check market status first
const { data } = await client.users.getMarkets(walletAddress);
const vnStatus = data.markets['VN']?.status;

if (vnStatus !== 'approved') {
  // Generate a fresh KYC link and redirect
  const { websdkUrl } = await client.kyc.generateLink({ walletAddress });
  window.location.href = websdkUrl;
}

Error handling

All errors thrown are instances of GaianError:

import { GaianError } from '@gaian-network/sdk';

try {
  await client.users.getById(999);
} catch (err) {
  if (err instanceof GaianError) {
    console.log(err.code);       // 'NOT_FOUND' | 'UNAUTHORIZED' | 'BAD_REQUEST' | ...
    console.log(err.statusCode); // 404
    console.log(err.message);    // API error message
    console.log(err.details);    // raw response body
  }
}

| code | HTTP status | When | |--------|------------|------| | UNAUTHORIZED | 401 | Missing or invalid API key | | FORBIDDEN | 403 | Valid key, insufficient permissions | | NOT_FOUND | 404 | User or order does not exist | | BAD_REQUEST | 400 | Invalid request parameters | | CONFLICT | 409 | Resource already exists (user registration) | | SERVER_ERROR | 5xx | Gaian server error — retry with backoff | | NETWORK_ERROR | — | Network timeout or connection failure |


Environments

| Environment | User API | Payment API | |-------------|----------|-------------| | sandbox | https://dev-user.gaian-dev.network | https://dev-payments.gaian-dev.network | | production | https://user.gaian-dev.network | https://payments.gaian-dev.network |

Override base URLs for testing or proxying:

const client = new GaianClient({
  apiKey: 'test-key',
  baseUrls: {
    user: 'http://localhost:3001',
    payment: 'http://localhost:3002',
  },
});

Requirements

  • Node.js ≥ 18 (native fetch)
  • TypeScript ≥ 5.0 (for exactOptionalPropertyTypes)

License

MIT