iotaledger / iotaledger/ts-packages

gRPC client for the IOTA TS SDK

Open
#334 0 comments 0 reactions 1 assignee Claimed by @evavirseda View on GitHub
enhancement ts-sdk
Dominant language
TypeScript
Stars
3
Forks
3
Avg merge
1d 2h
Merged PRs (30d)
12

Description

The Rust SDK ships a gRPC client (`iota-sdk-grpc-client`). TypeScript has none, so anyone writing an indexer, bridge watcher or analytics pipeline has to drop to Rust. Full proposal with wire captures and measurements: https://claude.ai/artifact/c6680f48-cfe3-4870-93eb-889697a7b3d7

## Shape

New workspace package `sdk/grpc` published as `@iota/grpc` at 0.x. Connect-ES (`@bufbuild/protobuf` v2 + `@connectrpc/connect`), codegen via `buf generate` + `protoc-gen-es` from the protos in `external/iota`, generated output committed.

Nothing in `@iota/iota-sdk` changes: no new exports, no new deps, no version bump. Wallet, Explorer, Dashboard and the dapps are untouched.

## Why it is not a quick port of Sui's client

In Sui's proto `GetObjects`, `GetTransactions` and `GetCheckpoint` are unary. In ours they are **server-streaming**, because genesis and epoch-boundary checkpoints exceed the message limit and the node fragments a logical response across several stream messages. The client has to reassemble. Sui's TS client has no reassembly layer, so it is not a starting point.

Three contracts to implement:

- `GetObjects` / `GetTransactions`: concatenate batches across messages using `has_next`, one result slot per request in request order. Fail loudly on a truncated stream or a count mismatch.
- `GetCheckpoint` / `StreamCheckpoints`: buffer `CheckpointData` frames per checkpoint (`Checkpoint` header, then N `ExecutedTransactions` / `Events` batches, closed by an `EndMarker` whose sequence number must match). `Progress` frames carry no data.
- `ListOwnedObjects` / `ListDynamicFields` / `ListPackageVersions`: unary cursor paging, but the server also truncates a page to fit `max_message_size_bytes`, so a short page is not the end of the collection.

Always send `max_message_size_bytes` derived from a single configured decode limit, same as the Rust client.

Reassembly must never be bypassable. There should be no public API handing a caller a raw frame stream, that is how a partial checkpoint silently becomes an empty one.

## Server-side only in v1

The public endpoints are plain gRPC over HTTP/2. Verified against `grpc.mainnet.iota.cafe`: a `application/grpc-web+proto` request comes back as `application/grpc` with trailers, CORS preflight returns no `access-control-allow-origin`, and `iota-grpc-server` registers its tonic services with no `tonic-web` layer. Browsers cannot reach it, so v1 targets Node, Bun and Deno. Design the transport pluggable so browser support is a new transport factory later, not a rewrite.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.