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

@rddevxclnc/tlx-sdk

v0.1.0

Published

Native Node.js SDK for the TLX document exchange platform. Built on the Rust `tlx-sdk` core via [napi-rs](https://napi.rs), providing RSA-4096 key generation, JWE encryption/decryption, ETDA message validation, and TLX platform API access.

Downloads

198

Readme

tlx-sdk

Native Node.js SDK for the TLX document exchange platform. Built on the Rust tlx-sdk core via napi-rs, providing RSA-4096 key generation, JWE encryption/decryption, ETDA message validation, and TLX platform API access.

Installation

npm install tlx-sdk

Pre-compiled native binaries are included for:

  • Linux x64 (glibc)
  • macOS ARM64 (Apple Silicon)
  • macOS x64 (Intel)

No Rust toolchain or C compiler is required.

Quick Start (JavaScript)

const {
  generateKeyPair,
  encryptMessage,
  decryptMessage,
  validateMessage,
} = require("tlx-sdk");

// 1. Generate an RSA-4096 key pair
const keys = generateKeyPair("my-secure-passphrase");
console.log("Public JWK:", keys.publicJwk);
console.log("Encrypted private key:", keys.privateJwkEncrypted);

// 2. Build an ETDA message
const message = JSON.stringify({
  version: "1.0",
  sender_tax_id: "1234567890123",
  receiver_tax_id: "9876543210987",
  document_type: "invoice",
  payload: "SGVsbG8gV29ybGQ=",
  timestamp: new Date().toISOString(),
});

// 3. Validate the message
validateMessage(message);

// 4. Encrypt the message with the recipient's public key
const jwe = encryptMessage(message, keys.publicJwk);
console.log("JWE:", jwe);

// 5. Decrypt the message with the private key
const decrypted = decryptMessage(jwe, keys.privateJwkEncrypted, "my-secure-passphrase");
const parsed = JSON.parse(decrypted);
console.log("Decrypted payload:", parsed.payload);

TypeScript Usage

import {
  generateKeyPair,
  encryptMessage,
  decryptMessage,
  validateMessage,
  registerPublicKey,
  getPartnerKey,
  listPartnerKeys,
  type KeyPairResult,
  type RegisteredKeyResult,
} from "tlx-sdk";

// Key generation returns a typed KeyPairResult
const keys: KeyPairResult = generateKeyPair("my-secure-passphrase");

const message: string = JSON.stringify({
  version: "1.0",
  sender_tax_id: "1234567890123",
  receiver_tax_id: "9876543210987",
  document_type: "invoice",
  payload: "SGVsbG8gV29ybGQ=",
  timestamp: new Date().toISOString(),
});

// Validate, encrypt, and decrypt
validateMessage(message);
const jwe: string = encryptMessage(message, keys.publicJwk);
const decrypted: string = decryptMessage(jwe, keys.privateJwkEncrypted, "my-secure-passphrase");

// Async TLX platform operations return Promises
async function registerAndFetchKeys(): Promise<void> {
  const baseUrl = "https://api.tlx.or.th";
  const apiKey = "your-api-key";

  // Register a public key
  const registered: RegisteredKeyResult = await registerPublicKey(
    baseUrl,
    apiKey,
    "participant-001",
    keys.publicJwk,
  );
  console.log("Registered key ID:", registered.keyId);

  // Fetch a partner's public key
  const partnerJwk: string = await getPartnerKey(
    baseUrl,
    apiKey,
    "partner-002",
    registered.keyId,
  );

  // List all active keys for a partner
  const partnerKeys: RegisteredKeyResult[] = await listPartnerKeys(
    baseUrl,
    apiKey,
    "partner-002",
  );
  console.log("Partner has", partnerKeys.length, "active keys");
}

Error Handling

All SDK functions throw errors with a descriptive code prefix. Use try/catch to handle specific error types:

const { generateKeyPair, encryptMessage, decryptMessage } = require("tlx-sdk");

// Validation errors — empty passphrase, invalid messages
try {
  generateKeyPair("");
} catch (err) {
  if (err.message.includes("VALIDATION_ERROR")) {
    console.error("Validation failed:", err.message);
  }
}

// Crypto errors — wrong passphrase
try {
  decryptMessage(jwe, privateKey, "wrong-passphrase");
} catch (err) {
  if (err.message.includes("CRYPTO_ERROR")) {
    console.error("Decryption failed:", err.message);
  }
}

// JWE errors — tampered or malformed JWE
try {
  decryptMessage("invalid.jwe.string.here.x", privateKey, "my-passphrase");
} catch (err) {
  if (err.message.includes("JWE_ERROR")) {
    console.error("Invalid JWE:", err.message);
  }
}

// HTTP errors — platform API failures (async)
try {
  await registerPublicKey("https://api.tlx.or.th", "bad-key", "p-001", publicJwk);
} catch (err) {
  if (err.message.includes("HTTP_ERROR")) {
    console.error("API request failed:", err.message);
  }
}

Error Codes

| Code | Cause | |------|-------| | VALIDATION_ERROR | Empty passphrase, invalid ETDA message fields | | CRYPTO_ERROR | Wrong passphrase, key derivation failure | | JWE_ERROR | Tampered/malformed JWE, invalid recipient key | | HTTP_ERROR | TLX platform API returned an HTTP error | | KEY_NOT_FOUND | Requested key does not exist on the platform | | SERIALIZATION_ERROR | Malformed JSON input |

API Reference

Sync Functions

generateKeyPair(passphrase: string): KeyPairResult

Generate an RSA-4096 key pair. The private key is encrypted with the passphrase using AES-256-GCM.

validateMessage(messageJson: string): void

Validate a JSON message string against ETDA schema rules. Throws on invalid input.

encryptMessage(messageJson: string, recipientPublicJwkJson: string): string

Encrypt a message for a recipient. Returns a JWE Compact Serialization string (five base64url parts separated by dots).

decryptMessage(jweCompact: string, privateJwkEncrypted: string, passphrase: string): string

Decrypt a JWE string using an encrypted private key and passphrase. Returns the decrypted message as a JSON string.

Async Functions

registerPublicKey(baseUrl, apiKey, participantId, publicJwkJson): Promise<RegisteredKeyResult>

Register a public key with the TLX platform.

getPartnerKey(baseUrl, apiKey, partnerId, keyId): Promise<string>

Fetch a partner's public key as a JWK JSON string.

listPartnerKeys(baseUrl, apiKey, partnerId): Promise<RegisteredKeyResult[]>

List all active public keys for a partner.

Types

interface KeyPairResult {
  publicJwk: string;
  privateJwkEncrypted: string;
}

interface RegisteredKeyResult {
  keyId: string;
  createdAt: string;
  status: string;
}

License

MIT