hop-sdk
v0.1.0
Published
Client SDK for the Polkadot HOP protocol
Readme
hop-sdk
Client SDK for the Polkadot HOP protocol — send and claim data through ephemeral off-chain storage on Polkadot.
Status: HOP is live on the Polkadot Previewnet.
What is HOP
Transferring data peer-to-peer requires both parties to be online at the same time. Posting every offline transfer to the chain wastes block allowance, adds latency, and keeps data around far longer than needed.
HOP is an ephemeral off-chain data pool hosted by Bulletin Chain collators. The sender uploads data to a collator, signals the receiver through the statement store, and the receiver claims it directly — no on-chain transaction required. Data lives for up to 24 hours; if unclaimed, the collator promotes it to Bulletin Chain storage as a last-resort fallback.
Why this SDK
The HOP protocol may change at the runtime level — new chunking strategies, proof formats, or transport protocols.
hop-sdk gives you a stable send / claim API so your application code doesn't break when the protocol evolves. Call HopClient.connect('previewnet') and the SDK resolves the right node endpoints for you.
Install
npm install hop-sdkQuick start
import { HopClient, HopTicket } from 'hop-sdk';
// sender
const client = await HopClient.connect('previewnet');
const data = new TextEncoder().encode('hello HOP');
const [ticket] = await client.send(data);
// pass ticket bytes to the recipient
const bytes = ticket.encode();
// recipient
const recipient = await HopClient.connect('previewnet');
const restored = HopTicket.decode(bytes);
const payload = await recipient.claim(restored);
console.log(new TextDecoder().decode(payload)); // "hello HOP"
client.destroy();
recipient.destroy();API reference
HopClient
| Method | Signature | Description |
|---|---|---|
| connect | static async connect(env: HopEnvironment): Promise<HopClient> | Connect to a HOP network by environment name |
| send | async send(data: Uint8Array, recipientCount?: number): Promise<HopTicket[]> | Send data into the pool. Returns one ticket per recipient. Max 64 MiB. |
| claim | async claim(ticket: HopTicket): Promise<Uint8Array> | Claim data from the pool using a ticket |
| destroy | destroy(): void | Release resources held by this client |
HopTicket
| Method | Signature | Description |
|---|---|---|
| encode | encode(): Uint8Array | Serialize to raw bytes |
| decode | static decode(bytes: Uint8Array): HopTicket | Deserialize from raw bytes |
Environments
| HopEnvironment | Network | Notes |
|---|---|---|
| local | Local dev node | For development against a local omni-node |
| previewnet | Polkadot Previewnet | For products |
Node endpoints are hardcoded per SDK release. They may change between versions, but your code stays the same — just call HopClient.connect('previewnet').
Tickets
A HopTicket is an opaque token returned by send(). Serialize it with encode() and restore it with HopTicket.decode():
const bytes = ticket.encode(); // Uint8Array (64 bytes)
const ticket = HopTicket.decode(bytes);Error handling
All SDK errors extend HopError, which has a code string and a message.
| Error class | Code | When |
|---|---|---|
| HopDataTooLargeError | DATA_TOO_LARGE | Data is empty or exceeds 64 MiB |
| HopPoolFullError | POOL_FULL | The pool has no remaining capacity |
| HopNotFoundError | NOT_FOUND | The requested entry does not exist in the pool |
| HopInvalidTicketError | INVALID_TICKET | Ticket bytes are malformed or have wrong length |
| HopNetworkError | NETWORK_ERROR | Transport-level failure (connection refused, timeout, etc.) |
| HopQuotaExceededError | QUOTA_EXCEEDED | Rate or usage quota exceeded |
import { HopPoolFullError } from 'hop-sdk';
try {
await client.send(data);
} catch (err) {
if (err instanceof HopPoolFullError) {
// wait and retry
}
throw err;
}Development
npm run build # build with tsup
npm test # run tests with vitest
npm run typecheck # type-check with tsc --noEmitLicense
Apache-2.0
