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

@keewallet/waas-sdk

v0.1.14

Published

KeeWallet WaaS SDK (server-side) — create custody wallets, list addresses, run WaaS Transfer / Private Transfer, create non-custodial Private Transfer pay-in orders, create Collect orders, and verify webhooks. HMAC-signed; holds the API secret, server-onl

Readme

@keewallet/waas-sdk

Server-side SDK for KeeWallet Wallet-as-a-Service operations, including custody wallets, addresses, transfers, transfer authorization, private transfers, collection orders, security factors, and webhook verification.

This package holds an API secret. Never import it into browser or mobile code.

Install

npm install @keewallet/waas-sdk

Node.js 18 or newer is required.

Create a client

import { createWaasClient } from '@keewallet/waas-sdk'

const waas = createWaasClient({
  apiKey: process.env.KEEWALLET_API_KEY,
  apiSecret: process.env.KEEWALLET_API_SECRET,
})

The default API origin is https://api.keewallet.io. Custom origins must use HTTPS; plain HTTP is accepted only for localhost development.

Capabilities and addresses

const service = await waas.service.version()
const capabilities = await waas.assets.capabilities({
  profile: 'waas',
  purpose: 'transfer',
  view: 'chains',
})

const addresses = await waas.addresses.list({
  page: 1,
  pageSize: 50,
  chainCode: 'tron',
  status: 'active',
})

Use the capability response as the authoritative source for supported chains, assets, and operations. user_wallet_id groups the addresses that belong to one end-user sub-wallet; transfer methods accept address strings, not internal IDs.

Custody wallets

const created = await waas.wallets.create(
  { walletName: 'Treasury' },
  { idempotencyKey: crypto.randomUUID() },
)

A mnemonic may be returned only once. Move it immediately to an approved offline backup process. Never log it, return it to a browser, or store it in analytics.

Transfers

const input = {
  chainCode: 'tron',
  token: 'USDT',
  fromAddress: 'T...',
  toAddress: 'T...',
  amount: '10',
  feeMode: 'platform_paid',
}

const quote = await waas.transfers.quote(input)
const order = await waas.transfers.create(input, {
  idempotencyKey: crypto.randomUUID(),
})
const status = await waas.transfers.get(order.order_no)

Use platform_paid when KeeWallet Credits cover network fees and sender_paid when the source address pays them. Quote before requesting user approval.

Direct transfers require a separately granted high-risk scope. Use the transfer authorization workflow when your policy requires maker/checker or end-user factors.

Transfer authorization

const authorization = await waas.transferAuthorizations.create(input, {
  idempotencyKey: crypto.randomUUID(),
})

const approved = await waas.transferAuthorizations.approve(
  authorization.authorization_id,
  {
    signingPayload: authorization.signing_payload,
    keewalletSignature: authorization.keewallet_signature,
    authorization: endUserFactor,
  },
  { idempotencyKey: crypto.randomUUID() },
)

Return signing payloads unchanged. KeeWallet validates authorization roles, credential binding, replay resistance, limits, and transaction policy.

Private transfer and collection

The main client exposes:

  • privateTransfers
  • selfCustodyPrivateTransfers
  • collect

Focused subpath clients are also available:

import { createCollectClient } from '@keewallet/waas-sdk/collect'
import { createSelfCustodyPrivateTransferClient } from '@keewallet/waas-sdk/self-custody-private-transfer'

Call collect.assets() before creating an order — it returns the usable chain_code + token pairs and shares its logic with order creation, so anything it lists can be used. Do not hard-code the result: not every chain takes both USDT and USDC (Optimism takes USDT only; TRON takes USDT plus native TRX), and Avalanche and Bitcoin are not supported for collect at all.

collect.listSettlements() (GET /waas/settlements) returns settlement records (completed settlements only) — same shape as the collect.settlement webhook. Reconcile orders against listOrders() and settlements against listSettlements(); they are separate books.

Collect order status is pending → received → settling → settled (or expired), with settled_at set once it settles. received and every later status mean the payment succeeded, so ship on received rather than waiting for settled.

Three webhooks, each answering one question:

  • collect.payment_received — per order, when it turns received. Carries received_amount (what the customer paid), service_fee and settle_amount, with settle_amount + service_fee === received_amount.
  • collect.settlement — one per settlement, when funds reach your main address. Carries settlement_no, order_nos, pending_amount, settlement_fee and settled_amount, with pending_amount - settlement_fee === settled_amount.
  • collect.order.expired — per order, when it expires unpaid. A late payment is no longer matched to it automatically. An order gets either collect.payment_received or this one, never both, so it settles that the order went unpaid; if your own record says paid, treat it as paid and ignore this event rather than rolling the status back.

Acknowledge all three with a 2xx even if you only act on one of them — anything else retries into the dead-letter state.

Fees come at two levels and are charged separately: the order fee is per order (a rate on the amount paid), the settlement fee is charged once per settlement and does not grow with the number of orders. With a 0.5% rate, a settlement fee of 1 and three payments of 100 / 90 / 200, the orders are charged 0.5 / 0.45 / 1 (settling 99.5 / 89.55 / 199) and the settlement moves 388.05 - 1 = 387.05 on-chain.

Collect webhooks are delivered up to 4 times: immediately, then 10s / 20s / 30s — the whole retry chain finishes within a minute. Any 2xx stops it.

Rate limits are counted on two independent axes: 100 requests/minute per API key and 120 per source IP (api_key_rate_limit_exceeded / ip_rate_limit_exceeded). Exceeding either returns 429 with Retry-After: 60. Treat webhooks as the primary channel and polling as a fallback — scan pending orders no more often than every 30 seconds, and fetch in bulk through the list endpoints (pageSize up to 100) instead of looping over single-order lookups.

Security factors

Use security.passkeys and security.totp to manage the supported transfer authorization factors. Factor verification results do not replace transaction authorization unless the approval endpoint consumes and verifies that factor.

Verify webhooks

Read the raw request body before any JSON middleware changes it:

const verified = waas.verifyWebhook({
  headers: request.headers,
  rawBody,
})

if (!verified.valid) throw new Error('Invalid KeeWallet webhook')

The signature covers the raw body and timestamp. Event identifiers and event types must come from the verified body.

Errors

import { KeeWalletWaasError } from '@keewallet/waas-sdk'

try {
  await waas.transfers.get('order_123')
} catch (error) {
  if (error instanceof KeeWalletWaasError) {
    console.error(error.code, error.status, error.requestId)
  }
}

Security

  • Keep API secrets and custody material in approved backend secret storage.
  • Never expose this package through a browser bundle.
  • Do not log authorization headers, mnemonics, private keys, TOTP seeds, or passkey assertions.
  • Use unique idempotency keys for write operations.
  • Verify webhook signatures against the unmodified raw body.
  • Grant the minimum API scopes required by each backend service.

License

Proprietary. Contact KeeWallet for licensing terms.