Skip to content

feat(sdk): gRPC streaming download fan-out + Swift core gRPC client#197

Open
Nic-dorman wants to merge 8 commits into
nic/v2-289-antd-stream-wiringfrom
v2-499-grpc-sdk-fanout
Open

feat(sdk): gRPC streaming download fan-out + Swift core gRPC client#197
Nic-dorman wants to merge 8 commits into
nic/v2-289-antd-stream-wiringfrom
v2-499-grpc-sdk-fanout

Conversation

@Nic-dorman

Copy link
Copy Markdown
Collaborator

Stacked on #196 (daemon wiring + REST SDK fan-out). Review/merge that first; this branch retargets to main automatically once it lands.

What

The gRPC counterpart to the REST streaming fan-out in #196 — adds data_stream / data_stream_public over gRPC to every SDK that ships a gRPC client:

  • gRPC streaming fan-out: go, py (sync + async), rust, csharp, java, kotlin, dart, ruby, cpp, elixir, swift. Proto regenerated with the new Stream RPC; idiomatic streaming return type per language. antd-js is REST-only (no gRPC client), so N/A.
  • Swift core gRPC client: replaces the 15 notImplemented() stubs (health / data / chunk / file get-put-cost + the two streaming methods) with a real implementation; regenerated data.{pb,grpc}.swift; adds GrpcCoreTests.
  • Ruby gRPC error-mapping fix: grpc_call constructed AntdError with positional/swapped args, so unmapped gRPC statuses raised ArgumentError instead of a mapped AntdError. Corrected, plus aligned tests and the no-gem fallback shell.

Validation

  • Mock-server gRPC round-trips green on Windows across the statically- and dynamically-typed SDKs.
  • dev2 (Linux): full Swift suite 57/57; Ruby 43 gRPC + 38 REST green; cpp / elixir green.
  • antd-rust compiles the canonical proto (with the new Stream RPC, supplied by the feat(antd): data streaming download — daemon wiring + REST SDK fan-out #196 base) via build.rs and passes cargo fmt --check.

Notes

🤖 Generated with Claude Code

@Nic-dorman Nic-dorman force-pushed the v2-499-grpc-sdk-fanout branch from ddc645d to 02537b9 Compare June 11, 2026 14:41
Nic-dorman and others added 8 commits June 11, 2026 15:45
…_public) — V2-499 Phase 2

Adds the streaming counterparts to buffered data_get/data_get_public on every
gRPC client, regenerating stubs for the new private Stream rpc. Each returns the
language's idiomatic streaming type: go io.ReadCloser; py Iterator/AsyncIterator
[bytes]; rust impl Stream<Bytes>; csharp IAsyncEnumerable<byte[]>; java
InputStream; kotlin Flow<ByteArray>; ruby block/Enumerator; dart Stream<List
<int>>; cpp DataSink callback; elixir {:ok, Enumerable} of binaries. swift gets
notImplemented() stubs (its whole gRPC client is stubbed pending a later ticket).

Built+tested green on Windows: go, py, rust(+clippy), csharp, java, kotlin,
ruby, dart. cpp/elixir build on dev2 (toolchains not on Windows).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hand-add StreamDataRequest message + Stream rpc to the gRPC stub (protoc-gen-elixir
unavailable on the Windows dev box); mirrors the StreamPublic entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
grpc_call's GRPC::BadStatus rescue built AntdError with positional, swapped
args (AntdError.new(e.code, e.message)) — AntdError#initialize takes
(message, status_code:), so any unmapped gRPC status raised ArgumentError
instead of the intended AntdError. Fixed to AntdError.new(e.message,
status_code: e.code).

Also align the test's no-grpc-gem fallback shell with the real client
(data_cost/file_cost return UploadCostEstimate, not a bare atto-tokens string)
and fix two test bugs surfaced once the real client runs on a box with the grpc
gem: cost assertions now read .cost, and the error-propagation test calls the
real file_put_public (not the nonexistent file_upload_public).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… (V2-480, V2-499)

Replaces the 15 notImplemented() stubs with real grpc-swift 2.x wiring:
health; data get/put (private+public) + cost; chunk get/put; file get/put
(private+public) + cost; and data streaming (dataStream/dataStreamPublic)
bridging the server-stream into an AsyncThrowingStream<Data,Error>. Mirrors the
already-wired wallet/external-signer methods + the go gRPC client mapping.

Adds GrpcCoreTests with in-process mock services covering every method.
Requires regenerating data.{pb,grpc}.swift for the new private Stream rpc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wrap the data_stream / data_stream_public stream.map closures per rustfmt — fixes the cargo fmt --all --check CI gate for the gRPC SDK fan-out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that the daemon gRPC PutDataResponse/PutPublicDataResponse carry these two fields, map them into each SDK gRPC client DataPut/DataPutPublic result (they were hardcoded to 0/empty or left default). Regenerated the data proto stubs for the committed-stub SDKs (go, py, ruby, dart, elixir, swift) and synced antd-kotlin vendored proto; build-time-regen SDKs (rust, java, kotlin, csharp, cpp) pick up the fields automatically. Refreshed now-inaccurate doc comments and the rust mock server.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Nic-dorman Nic-dorman force-pushed the v2-499-grpc-sdk-fanout branch from 02537b9 to c83d531 Compare June 11, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant