C++, GO, dotnet bindings via uniffi - #406
Open
dkackman wants to merge 97 commits into
Open
Conversation
Adds a new `uniffi` feature-gated backend to the bindy type conversion framework, mirroring the existing pyo3/napi/wasm backends, with `Uniffi` / `UniffiContext` marker types and conversions for BigInt, u64, u128 (as String), and bytes types (as Vec<u8>). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move uniffi dependency to workspace (consistent with all other deps) - Add impl_self!(i64) and impl_self!(i128) to uniffi_impls.rs so signed 64/128-bit types work with the uniffi feature - Fix redundant Ok(...)? wrapping in IntoRust impls for u64 and u128 - Clarify the usize comment to reference the lib.rs blanket impl Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create the uniffi/ crate as the C# bindings entry point. This required
several supporting changes:
- Add uniffi workspace member and create Cargo.toml, build.rs, src/lib.rs
- Hand-write the Clvm::alloc method dispatching ClvmType enum variants
- Add {usize} -> u32 mapping in bindings.json and FromRust/IntoRust impls
- Fix orphan rules: use concrete UniffiContext instead of generic T, add
Clone derive to wrapper structs, add blanket Arc<U> FromRust/IntoRust
- Emit static methods as free functions (UniFFI 0.28 limitation)
- Gate peer/rpc types behind uniffi feature alongside napi/pyo3
- Add chia-sdk-client and chia-ssl deps to bindy uniffi feature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the num-bigint dependency from the uniffi crate (BigInt conversions live entirely in bindy/src/uniffi_impls.rs). Adds a comment above Clvm::alloc explaining that nil/int/bool/string/bytes must go through typed helper methods in the UniFFI backend rather than the dynamic alloc path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also fix String.Format ambiguity in generated bindings where Clvm.String(string) method shadowed System.String within the Clvm class body. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Clvm class defines a String(string) method which shadows System.String in the class body, causing CS0119 on the ObjectDisposedException / OverflowException guard lines. Patch the two affected call sites in the generated file to use System.String.Format explicitly. Also suppress a nullability warning in CurryRoundtrip by asserting non-null inline with the null-forgiving operator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the manual sed step with a PatchClvmStringAmbiguity MSBuild target that runs BeforeTargets="CoreCompile" on every build. The patch is idempotent, so regenerating the bindings and running dotnet test is enough — no separate script needed. Update README to remove the manual patch step and reference the build target instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use RoslynCodeTaskFactory to apply the String.Format fix in pure .NET, eliminating the sed dependency. Works identically on Windows, macOS, and Linux with no external tools. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also adds InternalsVisibleTo in ChiaWalletSdk.csproj so the test assembly can access the internal types in the generated bindings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows the chia.wallet.dotnet test project to access internal SDK types. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dkackman
marked this pull request as draft
June 2, 2026 00:39
Closed
Adds set_request_timeout, RpcClientOptions, the *_with_options RPC factories, and the new PeerOptions timeout fields to the committed .pyi, matching the generator output checked by CI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dkackman
marked this pull request as ready for review
June 3, 2026 17:04
When a request_timeout fires, the oneshot receiver was dropped but the sender entry stayed in the RequestMap (purged only lazily on the next insert). A later request could reuse that id before the peer's delayed response arrived, causing the stale response to be delivered to the unrelated newer request. Remove the id explicitly on timeout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ReplaceInFile/ReplaceInFileRegex tasks silently no-op'd when their pattern matched zero times. For the internal->public visibility promotions that means a uniffi-bindgen-cs output change would ship a NuGet whose entire public API is internal (unusable) while the build stays green. Add an opt-in FailIfMissing flag and set it on the two always-present promotions so a generator format change fails loudly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The dotnet workflow packed and published to NuGet.org without ever running the .NET test suite (unlike the cpp and go workflows). Add a test job that builds the native lib, generates the bindings, and runs dotnet test, and make pack depend on it so publish is gated on tests passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The workflow triggered on every tag ("**") and fed GITHUB_REF_NAME
verbatim into dotnet pack, so a non-semver tag (e.g. "latest") or a
v-prefixed tag would fail the pack or publish a malformed version to
NuGet.org. Restrict the tag trigger to semver-shaped tags, strip an
optional leading 'v', and validate the version (via an env var rather
than direct interpolation) so a bad tag fails fast.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a regression test that drives a request to timeout against a silent in-process websocket server and asserts the RequestMap is emptied, so a future change can't reintroduce the stale-entry / id-reuse misrouting bug. Adds a test-only RequestMap::len() helper and a tokio dev-dependency (net/macros) for the in-process server. Also restructures the timeout arm in request_raw as an if/else (no behavior change) to satisfy the clippy single_match_else lint introduced by the earlier fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… check The previous FailIfMissing flag asserted that the `internal `->`public ` replacement *fired*, which broke idempotency: the generated bindings file persists across builds, so the target re-runs over an already-promoted file (e.g. dotnet pack then dotnet test) where the `internal ` patterns are legitimately gone, causing a false build failure. Replace it with an AssertFileContains check on the desired end state (public ChiaWalletSdkMethods + a core public domain type). This is idempotent — it passes whether the file was just promoted or already public — yet still fails loudly if a uniffi-bindgen-cs format change leaves the public API internal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds UniFFI as a fourth bindings backend alongside the existing pyo3, napi, and wasm targets, enabling generation of C++, Go, and .NET (C#) bindings for the Chia Wallet SDK from a single Rust source.
What's included
block_on)Notes
Timeouts
Because the C++ converts async operations to synchronous ones, I introduced timeout options that get passed down to
reqwestand websockets. These are opt-in so current behavior doesn't change. This could also be done as a separate PR but without them those synchronous calls have no cancellation mechanism for C++.uniffi plugin gaps
There are a couple of places where uniffi-* is not generating valid code. I've used post processing string replacement to get around those gaps. Updates to uniffi plugin versions (which do not seem to happen often) need to be handled carefully.