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

@velocity-chain/sdk

v0.5.2

Published

TypeScript SDK for velocity-node. Isomorphic core with Node and browser entry points.

Readme

velocity-js-sdk

TypeScript / JavaScript SDK for velocity-node. Browser and Node analog of the C# velocity-unity-sdk.

Requires Node.js 22+ (or any runtime with native fetch, WebCrypto, and ReadableStream).

Contents

Install

npm install @velocity-chain/sdk

Published as @velocity-chain/sdk on npm public.

Quick start — read a balance

import { createRawClient, VelocityApiException } from "@velocity-chain/sdk";

const raw = createRawClient({ baseUrl: "http://localhost:3000" });
const desc = raw.balance({
  account: "alice",
  namespace: "astralwars",
  token: "GOLD",
});

const res = await fetch(desc.url, { method: desc.method, headers: desc.headers });
if (!res.ok) throw new VelocityApiException(`HTTP ${res.status}`, res.status, await res.json());
const balance = await res.json(); // { balance, height, ... } — `balance` is a u64 string on the wire

Want runtime validation + bigint coercion? Use the typed client from @velocity-chain/sdk/schemas — it wraps the raw client with Zod parses and decodes u64 fields (heights, amounts, *_at_unix timestamps) as bigint:

import { createTypedClient } from "@velocity-chain/sdk/schemas";

const client = createTypedClient({ baseUrl: "http://localhost:3000" });
const balance = await client.balance({
  account: "alice",
  namespace: "astralwars",
  token: "GOLD",
});
// typeof balance.balance === "bigint"
// typeof balance.height === "bigint"

Sub-packages

| Import path | What it ships | Runtime | |---|---|---| | @velocity-chain/sdk | Types, raw HTTP descriptors, crypto, borsh, action signing | Isomorphic | | @velocity-chain/sdk/schemas | Zod schemas + typed client + signerOf | Isomorphic | | @velocity-chain/sdk/identity | velocity-identity client (port 4100) | Isomorphic | | @velocity-chain/sdk/wallet | velocity-wallet client (port 4200) | Isomorphic | | @velocity-chain/sdk/browser | Session holder, SSE block subscriber, bridge pollers | Browser-safe (no node:*) | | @velocity-chain/sdk/server | Admin actions, session-key issuance, headless BridgeOut | Node only |

The main entry types-only graph is Zod-free and stays so under a bundle-audit guard. Consumers who only import types pay zero runtime cost. Sub-paths (/schemas, /identity, /wallet, /browser, /server) are opt-in and may pull Zod for runtime validation — the audit allows them by design.

Action signing

The SDK ships ed25519 signing helpers for every dApp-callable variant of velocity-node's ChainAction union (23 kinds; consensus-only variants like BridgeIn/AttestBatch/CommitteeChangeset are out of scope). Each helper pairs the right domain tag with the borsh-serialized preimage and returns a SignedAction with authorityKey + signature as Uint8Array.

import { signTransfer, signSwap, signBridgeOut } from "@velocity-chain/sdk";

const seed: Uint8Array = /* 32-byte ed25519 seed */;

const signedTransfer = await signTransfer(
  {
    from: "alice",
    to: "bob",
    toNamespace: "astralwars",
    token: { namespace: "astralwars", name: "GOLD" },
    amount: 100n,
  },
  seed,
);
// signedTransfer.authorityKey   — 32 bytes
// signedTransfer.signature      — 64 bytes
// signedTransfer.preimage       — borsh-serialized payload (for verification)

Available signing helpers:

| Phase | Helpers | |---|---| | Token movements | signMint, signTransfer, signBurn | | Account lifecycle | signRegisterAccount, signAddAccountKey, signRevokeAccountKey, signRegisterSessionKey | | Namespace lifecycle | signNamespaceAdmin, signPlayerManage, signDepositFuel | | Capability admin | signGrantCapability, signGrantCrossNamespaceAccess, signRevokeCrossNamespaceAccess, signPurchaseCapability | | Phase 3 fixed-shop pools | signCreateSwapPool, signSetSwapRate, signSwap | | Phase 4 AMM pools | signCreateAmmPool, signAddLiquidity, signRemoveLiquidity, signAmmSwap | | Phase 5 flash loans | signFlashSwap | | Bridge | signBridgeOut |

Byte-exact correctness of every signing preimage is verified against chain's bridge_golden.rs in colocated *.test.ts files — drift here trips CI before it ships.

Bridge out (server-side, headless)

For headless backends (game server, marketplace, CLI) that hold an authorized account-key seed and want to bridge tokens without a wallet round-trip, the /server entry has a single-call helper:

import { submitBridgeOut } from "@velocity-chain/sdk/server";

const result = await submitBridgeOut(
  {
    baseUrl: "http://localhost:3000",
    accountKeySeed: loadFromVault(),
  },
  {
    namespace: "astralwars",
    from: "alice",
    token: { namespace: "astralwars", name: "gold" },
    amount: 100n,
    destinationChain: "solana",
    destination: solanaRecipientPubkeyBytes, // Uint8Array(32)
    nonce: 7n, // pre-fetch via raw.bridgeNonce({ account })
  },
);
// result.eventHash, result.height (bigint), result.proofUrl

The helper signs the BridgeOut payload, builds the wrapped { signed_action } envelope chain accepts at POST /bridge-out, and parses the response so height decodes as bigint.

…and wait for delivery (submitBridgeOutAndPoll)

When a backend wants the combined "sign + submit + wait until the destination chain confirms" cycle as one await:

import { submitBridgeOutAndPoll } from "@velocity-chain/sdk/server";

const { submission, terminal } = await submitBridgeOutAndPoll(
  { baseUrl: "http://localhost:3000", accountKeySeed: loadFromVault() },
  {
    namespace: "astralwars",
    from: "alice",
    token: { namespace: "astralwars", name: "gold" },
    amount: 100n,
    destinationChain: "solana",
    destination: solanaRecipientPubkeyBytes,
    nonce: 7n,
  },
  { intervalMs: 2000, timeoutMs: 30_000 },
);

if (terminal.status === "minted") {
  console.log("delivered as", terminal.destination_tx);
} else {
  console.error("relay failed:", terminal.reason);
}

Throws PollTimeoutError (re-exported from @velocity-chain/sdk/browser) when timeoutMs elapses without a terminal status. Default 30s matches the bridge-relayer p50 + headroom; tune via pollOptions.

Bridge out (browser, via wallet)

For browser flows where the user's keys live in a wallet service:

import { createTypedClient } from "@velocity-chain/sdk/schemas";
import { createWalletTypedClient } from "@velocity-chain/sdk/wallet";

const chain  = createTypedClient({ baseUrl: "http://localhost:3000" });
const wallet = createWalletTypedClient({ baseUrl: "http://localhost:4200" });

const { next_nonce } = await chain.bridgeNonce({ account: "alice" });

const signed = await wallet.sign(
  { token: signingClaimJWT },
  {
    kind: "BridgeOut",
    payload: {
      namespace: "astralwars",
      from: "alice",
      token: { namespace: "astralwars", name: "gold" },
      amount: 100n,
      destination_chain: "solana",
      destination: solanaRecipientHex,
      nonce: next_nonce,
    },
  },
);
// Submit signed.signed_action to chain's POST /bridge-out (wrapped path).

Typed block actions

BlockResponse.actions is a discriminated union over 31 chain variants (externally-tagged). Narrow with if ("Variant" in action):

import { BlockResponseSchema, signerOf, type ChainAction } from "@velocity-chain/sdk/schemas";

const block = BlockResponseSchema.parse(await res.json());

for (const action of block.actions) {
  if ("Mint" in action) {
    console.log(`mint ${action.Mint.amount} ${action.Mint.token.name} to ${action.Mint.to}`);
  } else if ("Swap" in action) {
    console.log(`swap ${action.Swap.amount_in} → ≥${action.Swap.min_amount_out}`);
  }
  // ... 29 more variants

  // Or pull the signer(s) uniformly across variants — handles the
  // per-variant field-name quirks (authority_*, admin_*, added_by,
  // owner_*, namespace_admin_*, etc.) and the multi-signer cases
  // (BridgeIn, CommitteeChangeset).
  for (const { key, signature } of signerOf(action)) {
    console.log(toHex(key), toHex(signature));
  }
}

Identity client

import { createIdentityTypedClient } from "@velocity-chain/sdk/identity";

const identity = createIdentityTypedClient({ baseUrl: "https://identity.example.com" });
await identity.signupEmail({
  email: "[email protected]",
  password: "…",
  accept_terms: true,
});
const me = await identity.me({ accessToken: bearerToken });

Cookie-based auth rides on every request via credentials: "include"; bearer attaches only on the documented allowlist endpoints (me, links, claimsSigning).

Wallet client

import { createWalletTypedClient } from "@velocity-chain/sdk/wallet";

const wallet = createWalletTypedClient({ baseUrl: "https://wallet.example.com" });
const result = await wallet.sign(
  { token: signingClaimJWT },
  { kind: "Transfer", payload: { /* ... */ } },
);

Wallet is stateless — every authenticated call takes a per-request SigningClaim.

Browser

import {
  BridgeSession,
  createRawClient,
  pollBridgeOut,
  PollTimeoutError,
  subscribeBlocks,
} from "@velocity-chain/sdk/browser";

const session = new BridgeSession({
  seed: walletIssuedSeed,
  publicKey: walletIssuedPubkey,
  expiresAtUnix: 1_700_000_000n,
});

const handle = subscribeBlocks({
  baseUrl: "http://localhost:3000",
  from: 0,
  onEvent: (msg) => console.log(msg.data),
});
// handle.close() to stop

const raw = createRawClient({ baseUrl: "http://localhost:3000" });
try {
  const status = await pollBridgeOut(
    raw,
    { eventHash: "..." },
    { intervalMs: 2000, timeoutMs: 30_000 },
  );
  // status.confirmed_at_unix is bigint
} catch (err) {
  if (err instanceof PollTimeoutError) { /* timed out */ }
}

The /browser entry has zero node:* imports — enforced by a bundle-audit test that fails CI on any leak.

Server

import { issueSessionKey, submitBridgeOut } from "@velocity-chain/sdk/server";

const session = await issueSessionKey(
  {
    baseUrl: "http://localhost:3000",
    namespaceAdminSeed: loadFromVault(),
  },
  {
    namespace: "astralwars",
    username: "alice",
    ttlSeconds: 900,
  },
);
// session.sessionSeed → hand off to the player; SDK does not persist it

The /server entry holds the namespace-admin seed in process memory for the duration of a request. Backends typically load it from env / Vault / SecretsManager at boot.

Schema source of truth

Wire schemas live in @velocity-chain/schemas and are re-exported through @velocity-chain/sdk/schemas. The typed ChainActionSchema / BlockActionSchema discriminated union, all response shapes, and the action sub-enums (FlashStepSchema, NamespaceAdminOpSchema, PlayerManageOpSchema) come from there.

Wire-type discipline

velocity-blockchain is the source of truth for every byte on the wire. Golden vectors in its bridge_golden.rs are mirrored byte-for-byte in this SDK's test suite. If the SDK disagrees with velocity-node, the SDK is wrong.

Development

npm install
npm run typecheck
npm test          # 600+ tests across 60+ files
npm run build     # tsup → dist/ (ESM + CJS + d.ts)

Versioning

Pre-1.0. The wire surface covers every endpoint and action variant documented in CHANGELOG.md, but minor versions may still bring breaking changes as the velocity-node wire stabilizes.

A note on the npm scope

The package is @velocity-chain/sdk, not @velocity/sdk. The @velocity scope on npm public is owned by an unrelated party and was unclaimable; the SDK ships under @velocity-chain (the gitlab repo name velocity-js-sdk is unchanged).

License

Proprietary, source-available. Copyright (c) 2026 Surgent International FZ-LLC. All rights reserved.

Full license text: gitlab.syncad.com/hive/velocity-js-sdk/-/blob/main/LICENSE.

Copyright (c) 2026 Surgent International FZ-LLC. All rights reserved.

This software and associated documentation files (the "Software") are the
proprietary property of Surgent International FZ-LLC, registered in Ras Al Khaimah
Economic Zone (RAKEZ), United Arab Emirates.

No license, express or implied, is granted to any person or entity to use,
copy, modify, merge, publish, distribute, sublicense, or sell copies of the
Software, in whole or in part, without the prior written consent of Surgent
Gaming LLC.

The source code is made publicly visible for transparency and review purposes
only. Public visibility does not constitute a grant of any rights.

For licensing inquiries, contact: [email protected]