Skip to content

Latest commit

 

History

116 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AOSSIE ThruBox

 

Static Badge

Telegram Badge    X (formerly Twitter) Badge    Discord Badge    LinkedIn Badge    Youtube Badge

OpenSSF Scorecard    Best Practices    Protected by Gitleaks


ThruBox Client SDK

A zero-dependency TypeScript SDK for the ThruBox Server. Send, receive, and manage encrypted messages with a simple API. Works in Node.js 18+ and modern browsers.


🚀 Features

  • Zero Runtime Dependencies: Only devDependencies for build/test
  • Typed Errors: Specific error classes for rate limiting, payload size, not found, etc.
  • Automatic Retry: Exponential backoff on 5xx and network errors
  • Polling: Built-in poll() helper with a stop function
  • Dual Format: Ships ESM + CJS with TypeScript declarations
  • Tiny: ~2.5 KB minified

💻 Tech Stack

  • TypeScript 5+
  • tsup (build)
  • Vitest (testing)
  • Native fetch API (no HTTP library dependency)

🍀 Getting Started

Install

npm install @aossie-org/thrubox-client

Quick Start

import { RelayClient } from '@aossie-org/thrubox-client';

const relay = new RelayClient('https://relay.example.com');

// Send an encrypted message
await relay.send({
  to: '0xRecipientWallet',
  from: '0xSenderWallet',
  payload: encryptedBase64String,
});

// Receive messages
const messages = await relay.receive('0xMyWallet');

// Later, fetch only what arrived since
const lastSeq = messages.at(-1)?.seq ?? 0;
const fresh = await relay.receive('0xMyWallet', { after: lastSeq });

Messages stay on the relay until they expire (the server's ttl_days); there is no way to delete them.


🛠️ Development

To build and test the SDK itself (not just consume it):

git clone https://github.com/AOSSIE-Org/ThruBox-Client.git
cd ThruBox-Client
npm install

npm run build     # build ESM + CJS output with tsup
npm test          # run the Vitest suite
npm run coverage  # run tests with coverage
npm run lint      # ESLint

📖 API Reference

new RelayClient(baseUrl, options?)

Option Type Default Description
apiKey string — API key for authenticated servers
timeout number 10000 Request timeout in ms
retries number 3 Retry attempts on network errors / 5xx

relay.send(params): Promise<Message>

Send an encrypted message to the relay. The returned message carries the server-assigned id and, on ThruBox Server 1.0 or later, its seq. On those servers sending an identical message twice is safe: it is stored once and the existing message is returned.

relay.receive(address, options?): Promise<Message[]>

Fetch messages for a wallet address, oldest first.

Option Type Description
after number Only return messages whose seq is greater than this
limit number Return at most this many messages (1–1000). A full page means there may be more: ask again with after set to the last seq

On ThruBox Server 1.0 or later, every message has a seq: its position in the mailbox (1, 2, 3, …). It only increases and is never reused, so remembering the highest seq you have handled and passing it as after gives you exactly the new messages. Each device keeps its own cursor. Older servers send no seq and ignore after and limit, returning the whole mailbox.

relay.poll(address, callback, options?): () => void

Auto-poll for new messages. Returns a stop function.

Option Type Default Description
intervalMs number 10000 Time between polls
onError (error) => void logs Called when a poll or the callback fails
after number — Turns on cursor tracking, starting from this seq (0 for the whole mailbox)

Without after, every poll passes the whole mailbox to the callback. With after, each poll fetches only messages newer than the cursor, and the cursor moves forward once the callback returns (or its promise resolves). If the callback throws or rejects, the cursor stays put and the same messages are delivered again on the next poll, so a failed save is retried rather than lost.

const stop = relay.poll('0xMyWallet', async (messages) => {
  await saveLocally(messages); // throw to have them delivered again
}, { intervalMs: 5000, after: 0 });

// Later: stop polling
stop();

The next poll is scheduled after the callback finishes, so polls never overlap.

relay.health(): Promise<HealthResponse>

Check server health.


⚠️ Error Handling

import { RelayRateLimitError, RelayPayloadTooLargeError } from '@aossie-org/thrubox-client';

try {
  await relay.send({ to, from, payload });
} catch (e) {
  if (e instanceof RelayRateLimitError) {
    console.log(`Rate limited. Retry after ${e.retryAfter}s`);
  }
  if (e instanceof RelayPayloadTooLargeError) {
    console.log('Payload exceeds server limit');
  }
}

🔗 Repository Links

  1. ThruBox Client — This repository (TypeScript SDK)
  2. ThruBox Server — Go relay server

🙌 Contributing

⭐ Don't forget to star this repository if you find it useful! ⭐

Thank you for considering contributing to this project! Contributions are highly appreciated and welcomed. To ensure smooth collaboration, please refer to our Contribution Guidelines.


✨ Maintainers


📍 License

This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.


💪 Thanks To All Contributors

Thanks a lot for spending your time helping ThruBox grow. Keep rocking 🥂

Contributors

© 2025 AOSSIE

Releases

Packages

Used by

Contributors

Languages