Skip to content

feat(antd-csharp): gRPC external-signer prepare/finalize parity with REST - #146

Closed
Nic-dorman wants to merge 1 commit into
nic/v2-284-grpc-external-signer-prepare-finalizefrom
nic/v2-284-antd-csharp-grpc-external-signer
Closed

feat(antd-csharp): gRPC external-signer prepare/finalize parity with REST#146
Nic-dorman wants to merge 1 commit into
nic/v2-284-grpc-external-signer-prepare-finalizefrom
nic/v2-284-antd-csharp-grpc-external-signer

Conversation

@Nic-dorman

Copy link
Copy Markdown
Collaborator

Summary

Replaces 7 NotSupportedException stubs on AntdGrpcClient with real implementations. Consumers can now swap an AntdRestClient for an AntdGrpcClient without code change in the external-signer flow.

Depends on #140 (antd-side UploadService + chunks prepare/finalize).

Methods replaced

method purpose
PrepareUploadAsync(path, visibility) external-signer prepare for a file
PrepareUploadPublicAsync(path) convenience wrapper for visibility="public"
PrepareDataUploadAsync(data, visibility) external-signer prepare for in-memory bytes
FinalizeUploadAsync(uploadId, txHashes) finalize wave-batch upload
FinalizeMerkleUploadAsync(uploadId, winnerPoolHash) finalize merkle-batch upload
PrepareChunkUploadAsync(data) single-chunk external-signer prepare
FinalizeChunkUploadAsync(uploadId, txHashes) single-chunk finalize, returns address

Wallet stubs remain — wallet-over-gRPC is a separate ticket.

Implementation notes

  • New UploadService.UploadServiceClient _upload field constructed alongside the existing service clients.
  • Introduces an internal constructor that accepts pre-built service clients so tests can pass mock subclasses; the public string-target constructor delegates via GrpcChannel.ForAddress.
  • MapPrepareResponse helper builds PrepareUploadResult, populating merkle-only fields (Depth, PoolCommitments, MerklePaymentTimestamp) only when PaymentType == "merkle".

Project plumbing

  • Antd.Sdk.csproj picks up upload.proto and adds InternalsVisibleTo("Antd.Sdk.Tests") so the internal test constructor is visible to the test project.
  • Antd.Sdk.Tests.csproj adds the Grpc.Core.Testing NuGet package — provides TestCalls.AsyncUnaryCall<TResponse>(...), the canonical helper for wrapping a pre-canned Task<TResponse> in the AsyncUnaryCall<TResponse> return type the generated *Async methods produce.

Tests

New Antd.Sdk.Tests/GrpcClientTests.cs:

  • MockChunkServiceClient and MockUploadServiceClient subclass the generated service clients and override the relevant virtual *Async methods.
  • The other (unused) service clients are constructed with a stub CallInvoker that throws if exercised — keeps the constructor signature happy without spinning a real server.
  • 11 xunit cases parallel to the antd-rust / antd-go / antd-py / antd-java / antd-kotlin suites: visibility forwarded/omitted, public convenience wrapper, wave-batch vs merkle, DataMapAddress presence on public, merkle finalize, chunk already-stored short-circuit, chunk finalize body forwarding.

Gates passed on dev2

  • dotnet build Antd.Sdk/Antd.Sdk.csproj clean
  • dotnet test Antd.Sdk.Tests/Antd.Sdk.Tests.csproj — 43/43 (32 existing REST + 11 new gRPC)

…REST

Replaces 7 `NotSupportedException` stubs on `AntdGrpcClient` with real
implementations:

* `PrepareUploadAsync(path, visibility)` / `PrepareUploadPublicAsync(path)`
* `PrepareDataUploadAsync(data, visibility)`
* `FinalizeUploadAsync(uploadId, txHashes)` (wave-batch)
* `FinalizeMerkleUploadAsync(uploadId, winnerPoolHash)`
* `PrepareChunkUploadAsync(data)` / `FinalizeChunkUploadAsync(uploadId, txHashes)`

All return `Task<T>` and a consumer can swap an `AntdRestClient` for an
`AntdGrpcClient` without code change in the external-signer flow.

Wallet stubs remain — wallet-over-gRPC is a separate ticket.

Client (`AntdGrpcClient.cs`):

* New `UploadService.UploadServiceClient _upload` field constructed
  alongside the existing service clients.
* Introduces an internal constructor that accepts pre-built service
  clients so tests can pass mock subclasses; the public string-target
  constructor delegates via `GrpcChannel.ForAddress`.
* `MapPrepareResponse` helper builds `PrepareUploadResult`, populating
  merkle-only fields (`Depth`, `PoolCommitments`,
  `MerklePaymentTimestamp`) only when `PaymentType == "merkle"`.

Project plumbing:

* `Antd.Sdk.csproj` picks up `upload.proto` and adds
  `InternalsVisibleTo("Antd.Sdk.Tests")` so the internal constructor is
  visible to the test project.
* `Antd.Sdk.Tests.csproj` adds the `Grpc.Core.Testing` NuGet package
  for `TestCalls.AsyncUnaryCall` — the canonical helper for wrapping a
  pre-canned `Task<TResponse>` in the `AsyncUnaryCall<TResponse>`
  return type the generated `*Async` methods produce.

Tests (`Antd.Sdk.Tests/GrpcClientTests.cs`):

* New file. `MockChunkServiceClient` and `MockUploadServiceClient`
  subclass the generated service clients and override the relevant
  virtual `*Async` methods; the other services use a stub `CallInvoker`
  that throws if exercised.
* 11 xunit cases parallel to the antd-rust / antd-go / antd-py /
  antd-java / antd-kotlin suites: visibility forwarded/omitted, public
  convenience wrapper, wave-batch vs merkle, `data_map_address`
  presence on public, merkle `FinalizeMerkleUpload`, chunk
  already-stored short-circuit, chunk finalize body forwarding.

Gates on dev2:

* `dotnet build Antd.Sdk/` clean
* `dotnet test Antd.Sdk.Tests/` — 43/43 (32 existing REST + 11 new gRPC)

Depends on the antd-side daemon PR landing first.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Nic-dorman
Nic-dorman deleted the branch nic/v2-284-grpc-external-signer-prepare-finalize May 28, 2026 15:47
@Nic-dorman Nic-dorman closed this May 28, 2026
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