feat: UploadCostEstimate rich breakdown across all SDKs + /v1/files/cost#28
Merged
Nic-dorman merged 27 commits intomainfrom Apr 22, 2026
Merged
feat: UploadCostEstimate rich breakdown across all SDKs + /v1/files/cost#28Nic-dorman merged 27 commits intomainfrom
Nic-dorman merged 27 commits intomainfrom
Conversation
Replaces antd's per-chunk sequential get_store_quotes loop with a single
Client::estimate_upload_cost call (ant-client PR #44). That call samples
up to 5 chunk addresses and extrapolates median * 3, matching
SingleNodePayment::from_quotes.
Measured improvement on Arbitrum One mainnet from home NAT (4KB payload,
3 chunks):
- old handler: >15 min, timed out, 0 successful quotes
- new handler (warm cache): 63 s — 272 s across 4 samples, cost
identical at 35156250000000000 atto
Preserves CostResponse { cost } contract for wire-compat; later work
will extend the response shape with chunk_count / gas / payment_mode
and roll out across SDKs (antd-go first for Indelible).
Also adds the local-test stack to Cargo.toml:
- ant-core as path dep to ../../ant-client/ant-core
- [patch.crates-io] saorsa-core = path to ../../saorsa-core (for
PRs #91/#92 pre-release)
Local-test branch only — DO NOT merge upstream.
Phase 1 of the multi-SDK cost-estimate rollout. Previously antd only
exposed the storage cost as a single string; estimate_upload_cost
returns a richer shape. This change surfaces all four new fields on
both REST and gRPC while preserving wire-compat with existing clients:
proto/antd/v1/common.proto
Cost: added file_size (u64), chunk_count (u32),
estimated_gas_cost_wei (string), payment_mode (string).
New fields default to zero/empty for put/upload wrapping uses
of Cost, which are harmless noise for existing clients.
src/types.rs
CostResponse: added four Option<..> fields with
skip_serializing_if = "Option::is_none" so legacy REST clients see
the same JSON shape they do today.
src/rest/data.rs, src/rest/files.rs
Populate the new fields from the UploadCostEstimate.
src/grpc/service.rs
- Port get_cost and get_file_cost to estimate_upload_cost (same
shape as the REST handlers; get_cost stages bytes to a temp file).
- Add ..Default::default() on the three put/upload Cost wrapping
sites so they compile against the widened message.
- Import format_payment_mode from types.
Existing SDK wrappers that only read `cost` / `atto_tokens` keep
working. SDKs that want the rich view will be updated next (antd-go
first for Indelible).
…kdown
Phase 2 of the multi-SDK cost-estimate rollout. Surfaces the new
file_size / chunk_count / estimated_gas_cost_wei / payment_mode
fields added to the Cost message in Phase 1.
Prioritised first because Indelible consumes antd-go directly, and
the sampling-based estimator is the difference between a sub-minute
quote and a multi-minute timeout on slow real networks.
models.go
New UploadCostEstimate struct with all five fields.
client.go, grpc_client.go
Keep DataCost / FileCost returning a plain string for back-compat.
Add EstimateDataCost / EstimateFileCost returning *UploadCostEstimate.
Both REST and gRPC transports supported with identical signatures.
proto/antd/v1/{common,files}.pb.go
Regenerated from the updated proto. Cost message now has the four
new getters (FileSize, ChunkCount, EstimatedGasCostWei, PaymentMode).
client_test.go, grpc_client_test.go
Mock responses extended with the new fields.
New tests: TestEstimateDataCost, TestEstimateFileCost,
TestGrpcEstimateDataCost, TestGrpcEstimateFileCost.
Legacy TestDataCost / TestFileCost still pass — contract is
additive.
examples/03-files/main.go
Demonstrates the richer estimate output.
README.md
Method table updated with both legacy and new methods.
Regen command for future updates (same as README):
protoc --proto_path=antd/proto --go_out=antd-go/proto \
--go_opt=paths=source_relative \
--go_opt=Mantd/v1/common.proto=github.com/WithAutonomi/ant-sdk/antd-go/proto/antd/v1 \
... (see README "Generating Proto Stubs")
Phase 3 rollout — antd-rust. Mirrors the Go SDK additions. models.rs New UploadCostEstimate struct with cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode. client.rs, grpc_client.rs Existing data_cost / file_cost keep their String return for back-compat. New estimate_data_cost / estimate_file_cost return UploadCostEstimate. REST reads the new JSON fields; gRPC reads the new Cost message fields. tests.rs, grpc_tests.rs Mock responses extended with the new fields. 4 new tests: test_estimate_data_cost, test_estimate_file_cost, test_grpc_estimate_data_cost, test_grpc_estimate_file_cost. Add ..Default::default() on the three v1::Cost wrapping sites (put_public, put_private, chunk_put) so they compile against the widened message. README.md Method table updated. Also adds target-dev/ to .gitignore — used when the main target/ is locked by a running antd binary.
Phase 3 rollout — antd-py. Mirrors the Go and Rust SDK additions.
models.py
New UploadCostEstimate dataclass with cost, file_size, chunk_count,
estimated_gas_cost_wei, payment_mode.
_rest.py, _grpc.py
Existing data_cost / file_cost keep their str return for
back-compat. New estimate_data_cost / estimate_file_cost return
UploadCostEstimate. Both sync and async transport variants.
_proto/antd/v1/common_pb2.{py,pyi}
Regenerated via scripts/generate_proto.py — Cost message now has
the four new fields.
__init__.py
UploadCostEstimate exported from the top-level antd package.
tests/test_rest_client.py
/v1/data/cost mock response extended with the new fields.
New test class TestEstimateDataCost verifies the full breakdown.
README.md
Method table updated.
Phase 3 rollout — antd-js. Mirrors the Go/Rust/Py SDK additions. models.ts New UploadCostEstimate interface with cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode. rest-client.ts Existing dataCost / fileCost keep their string return for back-compat. New estimateDataCost / estimateFileCost return UploadCostEstimate. index.ts UploadCostEstimate exported from the package root. rest-client.test.ts /v1/data/cost mock extended with the new fields. New test estimateDataCost() verifies the full breakdown. README.md Method table updated.
Follows the policy decision that there are no legacy consumers — no
need to preserve a reduced-shape response for compat.
proto/antd/v1/common.proto
Drop the "only set for estimates" comment on the 4 rich fields;
they are always populated now.
src/types.rs
CostResponse: file_size, chunk_count, estimated_gas_cost_wei,
payment_mode are now plain scalars (no Option, no
skip_serializing_if). REST clients always see all 5 fields.
src/rest/{data,files}.rs
Drop the `Some(..)` wrapping when constructing CostResponse.
Wire-level: the Cost proto3 message already always serialised all
fields (proto3 scalars have no optional distinction from zero). JSON
consumers gain four always-present fields.
No consumers yet of the added Estimate* methods. Collapse back to single DataCost/FileCost methods that return *UploadCostEstimate. client.go, grpc_client.go DataCost and FileCost now return (*UploadCostEstimate, error). Estimate* variants deleted. client_test.go, grpc_client_test.go Tests rewritten to verify the new shape. 2 net tests kept (DataCost, FileCost) instead of 4 (DataCost + EstimateDataCost etc). examples/03-files/main.go Updated to the single-method form. README.md Method table collapsed.
Mirrors the antd-go change. No consumers yet, so collapse the two-method pair (data_cost/estimate_data_cost) into a single method returning UploadCostEstimate. src/client.rs, src/grpc_client.rs data_cost/file_cost now return Result<UploadCostEstimate, _>. estimate_* methods removed. src/tests.rs, src/grpc_tests.rs Tests rewritten; 4 duplicate tests removed (net -4). examples/02-data.rs, examples/04-files.rs Updated to print the rich estimate. README.md Method table collapsed.
Mirrors antd-go and antd-rust retrofits. Single-method API returning UploadCostEstimate instead of a data_cost/estimate_data_cost pair. src/antd/_rest.py, src/antd/_grpc.py Sync + async data_cost/file_cost now return UploadCostEstimate. estimate_* methods removed. tests/test_rest_client.py TestDataCost verifies the full breakdown; TestEstimateDataCost deleted. examples/02_data.py, examples/04_files.py Updated to print size/chunks/gas/mode. README.md Method table collapsed.
Mirrors antd-go / antd-rust / antd-py retrofits. Single-method API returning UploadCostEstimate. src/rest-client.ts dataCost and fileCost return Promise<UploadCostEstimate>. estimate* variants removed. JSON shape is destructured as required (not optional) fields — the antd Cost message always populates them. src/rest-client.test.ts Merged tests into a single dataCost describe block. examples/02-data.ts, examples/04-files.ts Print the rich estimate. README.md Method table collapsed.
Phase 3 rollout — antd-java. Follows the simplified contract: a single method returning the rich estimate, no legacy string-only variant. src/main/java/com/autonomi/antd/models/UploadCostEstimate.java New record with cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode. src/main/java/com/autonomi/antd/AntdClient.java src/main/java/com/autonomi/antd/AsyncAntdClient.java dataCost/fileCost (sync + CompletableFuture async) now return UploadCostEstimate. src/main/java/com/autonomi/antd/GrpcAntdClient.java Same for gRPC transport — reads the new Cost proto fields. src/test/java/com/autonomi/antd/AntdClientTest.java src/test/java/com/autonomi/antd/GrpcAntdClientTest.java Mock responses extended, tests verify full breakdown. README.md Method table updated.
…imate Phase 3 rollout — antd-csharp. Follows the simplified contract. Antd.Sdk/Models.cs New UploadCostEstimate record (Cost, FileSize, ChunkCount, EstimatedGasCostWei, PaymentMode). Antd.Sdk/AntdRestClient.cs, Antd.Sdk/AntdGrpcClient.cs DataCostAsync/FileCostAsync now return Task<UploadCostEstimate>. Internal CostDto extended with the 4 new fields (defaulted so old responses still deserialise). Antd.Sdk/IAntdClient.cs Interface updated. Antd.Sdk.Tests/UnitTests.cs DataCostAsync test verifies full breakdown. Antd.Sdk.Tests/TestRunner.cs Integration harness prints rich estimate. README.md Method table updated.
Phase 3 rollout — antd-kotlin.
lib/src/main/kotlin/com/autonomi/sdk/Models.kt
New UploadCostEstimate data class (cost, fileSize, chunkCount,
estimatedGasCostWei, paymentMode).
Internal CostDto gains the 4 new fields with kotlinx-serialization
@SerialName + defaults so old responses still parse.
lib/src/main/kotlin/com/autonomi/sdk/{AntdRestClient,AntdGrpcClient,IAntdClient}.kt
dataCost/fileCost now return UploadCostEstimate.
lib/src/test/kotlin/com/autonomi/sdk/RestClientTest.kt
Mock responses extended; tests verify full breakdown.
examples/src/main/kotlin/com/autonomi/examples/Main.kt
Prints rich estimate.
Phase 3 rollout — antd-swift. Sources/AntdSdk/Models.swift New UploadCostEstimate struct (cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode). Sources/AntdSdk/AntdRestClient.swift CostDTO extended with 4 new optional fields; dataCost/fileCost now return UploadCostEstimate. Sources/AntdSdk/AntdGrpcClient.swift Stub signatures updated (gRPC transport still not implemented). Sources/AntdSdk/AntdClientProtocol.swift Protocol updated. Sources/AntdExamples/Main.swift Prints rich estimate. Note: not build-verified locally (no swift toolchain on the dev host). The edits are structurally identical to the other SDKs.
Phase 3 rollout — antd-dart. lib/src/models.dart New UploadCostEstimate class with fromJson (cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode). lib/src/client.dart, lib/src/grpc_client.dart dataCost/fileCost now return Future<UploadCostEstimate>. lib/src/generated/ Regenerated via tool/generate_proto.sh. Cost message has 4 new fields (fileSize: Int64, chunkCount: int, estimatedGasCostWei, paymentMode). Not build-verified locally beyond protoc regen.
Phase 3 rollout — antd-cpp. include/antd/models.hpp New UploadCostEstimate struct (cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode). include/antd/client.hpp, include/antd/async_client.hpp data_cost/file_cost now return UploadCostEstimate (sync) and std::future<UploadCostEstimate> (async). src/client.cpp, src/async_client.cpp Implementations updated; JSON helpers populate the new fields. examples/02-data.cpp, examples/04-files.cpp Prints rich estimate. Not build-verified locally (no C++ toolchain preconfigured on host). The edits are structurally identical to the other SDKs.
Phase 3 rollout — antd-ruby. lib/antd/models.rb New UploadCostEstimate Struct (cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode). lib/antd/client.rb, lib/antd/grpc_client.rb data_cost/file_cost now return UploadCostEstimate. Ruby pb stubs are generated by the consumer (per README), so no committed pb files to regen here.
Phase 3 rollout — antd-php. src/Models/UploadCostEstimate.php New readonly class (cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode). src/AntdClient.php dataCost/fileCost (sync + PromiseInterface async) now return UploadCostEstimate.
Phase 3 rollout — antd-elixir.
lib/antd/models.ex
New Antd.UploadCostEstimate struct (cost, file_size, chunk_count,
estimated_gas_cost_wei, payment_mode).
lib/antd/client.ex, lib/antd/grpc_client.ex
data_cost/file_cost (and the !-raising variants) now return
{:ok, Antd.UploadCostEstimate.t()}.
Phase 3 rollout — antd-lua. src/antd/client.lua data_cost/file_cost now return a table with cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode (rather than a bare cost string). spec/client_spec.lua Mock responses extended; tests verify the full breakdown.
Phase 3 rollout — antd-zig. src/models.zig New UploadCostEstimate struct with deinit helper. src/json_helpers.zig parseCost renamed and reshaped to parseCostEstimate returning UploadCostEstimate. New dupeU64 helper for the numeric fields. src/antd.zig dataCost/fileCost now return !models.UploadCostEstimate. UploadCostEstimate re-exported alongside the other model aliases. examples/02-data.zig, examples/04-files.zig Print the rich estimate; call the deinit helper correctly. Not build-verified locally (no zig toolchain preconfigured on host).
Phase 3 rollout — antd-mcp. src/antd_mcp/server.py The estimate_cost tool now unpacks the UploadCostEstimate returned by antd-py's data_cost/file_cost into the MCP JSON response: cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode. Tool callers (agents) can now surface meaningful upload previews (size/chunks/gas/mode) to the user rather than just a cost number.
Updates every doc site surface so they match the simplified contract
(single method returning UploadCostEstimate, no string-only variant).
Top-level:
skill.md
The *_cost entries now mention UploadCostEstimate with its five
fields.
llms-full.txt
Cost message listing, Model Types table, and every per-SDK method
signature snippet updated (TS, Py, C#, Kotlin, Swift, Go, Java,
Rust, C++, Ruby, PHP, Dart, Lua, Elixir, Zig).
antd/README.md, antd-mcp/README.md
REST endpoint / MCP tool descriptions note the richer response
shape.
Per-SDK READMEs (cpp, ruby, php, elixir, lua, zig, dart):
Method tables now include "— returns UploadCostEstimate with size,
chunks, gas, payment mode" (or equivalent language-specific form).
Zig's ownership notes updated — UploadCostEstimate has a deinit,
dataCost/fileCost no longer return raw byte slices.
docs/architecture.md, docs/tutorial-store-retrieve.md,
docs/quickstart-*.md (15 files):
Every cost-estimation code sample captures the result as `est` and
prints size/chunks/cost/gas/mode instead of just a bare cost string.
No source code changes in this commit — purely documentation.
Follow-up to the Phase 3 rollout — these three SDKs had test files that still expected the legacy string return. Found when running the full local test sweep: antd-dart/test/client_test.dart Mock responses extended; assertions verify est.cost, fileSize, chunkCount, estimatedGasCostWei, paymentMode. 40/40 tests pass. antd-ruby/test/test_client.rb Same for test_data_cost and test_file_cost. Ruby Struct fields checked instead of a bare string. 24/24 client tests pass; 24/24 grpc tests pass. antd-php/tests/AntdClientTest.php testDataCost and testFileCost rewritten against UploadCostEstimate properties. Also removed a stale extra `false` argument from the fileCost call site. 21/21 tests pass.
File cost now sits alongside /v1/files/upload/public and /v1/files/download/public instead of an orphan /v1/cost/* namespace. Breaking wire change, but no external consumers yet. Also sweeps: - llms-full.txt: correct stale response shapes for data/files put + cost - scripts/test-api.sh, .ps1: replace four skipped sections with real curl round-trip tests (public data, files, private data, cost estimation) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the `ant-core = { path = ... }` and `saorsa-core = { path = ... }`
overrides with remote git refs so CI runners can resolve them:
- ant-core → git dep on WithAutonomi/ant-client main. Now that ant-client
PR #44 (feat/file-cost-estimate) has merged, `Client::estimate_upload_cost`
is available from the git URL directly.
- saorsa-core [patch.crates-io] → git pin to 50734d04, the merge commit of
saorsa-labs/saorsa-core PR #92 on upstream main. Preserves PRs #91/#92
(Windows IPv6 split-stack + mapped-v4 normalization) which ship after
v0.23.1. Drop the block once saorsa-core cuts a release that includes
both PRs.
Local behaviour unchanged; resolves the `unable to update .../ant-core`
and `.../saorsa-core` failures on CI clippy.
Co-Authored-By: Claude Opus 4.7 (1M context) <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
Upgrades the cost-estimation endpoints to return a full breakdown and ports the change across every SDK. Also renames the asymmetric
/v1/cost/fileroute.Server (antd)
POST /v1/data/costandPOST /v1/files/costnow back ontoant_core::Client::estimate_upload_cost, which samples up to 5 chunk addresses instead of quoting every chunk — dramatically faster on home-NAT / high-latency networks.CostResponseshape extended to{ cost, file_size, chunk_count, estimated_gas_cost_wei, payment_mode }(was just{ cost }). gRPCCostmessage gets the matching additions./v1/cost/file→/v1/files/costso file cost sits next to/v1/files/upload/publicand/v1/files/download/publicinstead of an orphan/v1/cost/*namespace. Breaking wire change, safe because no external consumers yet.SDKs (16 total)
Each SDK's
dataCost/fileCost(and async variants) now returns the richUploadCostEstimatestruct natively — legacy string-return helpers removed since there are no consumers:antd-go, antd-rust, antd-py, antd-js, antd-java, antd-csharp, antd-kotlin, antd-swift, antd-dart, antd-cpp, antd-ruby, antd-php, antd-elixir, antd-lua, antd-zig, antd-mcp.
Docs + scripts
llms.txt,llms-full.txt,antd/README.md,antd/openapi.yaml, all 15docs/quickstart-*.md+skill.mdrefreshed for the new shape + route.scripts/test-api.shandtest-api.ps1now exercise real curl round-trips for public data, chunks, files, private data, and both cost endpoints — four previously-skipped sections lit up.Upstream dependency pins
Server uses APIs that depend on changes merged upstream but not yet released:
feat/file-cost-estimate) — ✅ merged toWithAutonomi/ant-clientmainon 2026-04-22.antd/Cargo.tomlnow pullsant-coreviagit = "https://github.com/WithAutonomi/ant-client".saorsa-labs/saorsa-coremainbut post-dated the latestv0.23.1release.antd/Cargo.tomlpins via[patch.crates-io]to the PR #92 merge commit50734d04. Drop the pin once saorsa-core cuts a release > v0.23.1 that includes both PRs (critical for Windows operation — IPv6 split-stack + mapped-v4 normalization).Test plan
Check (antd)— green (clippy, fmt, docs, tests)API contract tests (antd-rust)— greenSecurity audit— greenscripts/test-api.shend-to-endluasocket.dllenv issue on this Windows host🤖 Generated with Claude Code