@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-sdkPre-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
