Skip to content

feat(antd): wire visibility through /v1/upload/prepare#57

Merged
Nic-dorman merged 2 commits into
mainfrom
feat/antd-prepare-upload-visibility
May 6, 2026
Merged

feat(antd): wire visibility through /v1/upload/prepare#57
Nic-dorman merged 2 commits into
mainfrom
feat/antd-prepare-upload-visibility

Conversation

@Nic-dorman
Copy link
Copy Markdown
Collaborator

@Nic-dorman Nic-dorman commented May 5, 2026

Summary

Wires visibility through /v1/upload/prepare and surfaces the bundled-DataMap address on /v1/upload/finalize. Bumps antd to 0.6.1.

The file-path side is fully unblocked against the pinned ant-cli-v0.2.2. The in-memory /v1/data/prepare side returns 501 for visibility:"public" until upstream data_prepare_upload_with_visibility merges; once it does, that 501 path flips to a real call (no other changes needed in this PR's footprint).

Mainnet validation (2026-05-06)

End-to-end external-signer wave-batch public upload validated on Arbitrum One mainnet against this branch (rebased on top of v0.6.0):

  • 10 KB test file → 3 data chunks. Public prepare returned 4 payments (private control returned 3) — DataMap chunk bundled into the same PaymentIntent.
  • Cost scaled proportionally: 0.0352 ANT private → 0.0469 ANT public (4/3 ratio, DataMap priced as one chunk).
  • ERC-20 approve tx + single payForQuotes tx covering all 4 quotes — atomic external-signer payment.
  • /v1/upload/finalize returned data_map_address populated; chunks_stored=4 matched the bundled payment count.
  • /v1/files/download/public {address: data_map_address} round-tripped the file byte-for-byte (SHA256 match).

Behavior

Caller Before After
/v1/upload/prepare {path} private prepare unchanged (omitting visibility is implicitly private)
/v1/upload/prepare {path, visibility:"public"} (field ignored, private prepare) public prepare — DataMap chunk bundled into the same PreparedUpload payment batch
/v1/upload/finalize returns {data_map, address?, chunks_stored} also returns data_map_address? when prepare was public
/v1/data/prepare {data, visibility:"public"} private prepare 501 until data_prepare_upload_with_visibility is exposed upstream
Any caller passing store_data_map: true unchanged unchanged — legacy path honored, paid by daemon wallet

Files

  • antd/src/types.rs:
    • PrepareUploadRequest, PrepareDataUploadRequest: optional visibility: Option<String>
    • FinalizeUploadResponse: optional data_map_address: Option<String> (skipped from JSON when None — old clients see no new fields)
    • New helper parse_visibility(Option<&str>) -> Result<ant_core::data::Visibility, String>
    • 7 new unit tests
  • antd/src/rest/upload.rs:
    • prepare_upload now calls file_prepare_upload_with_visibility instead of file_prepare_upload
    • prepare_data_upload returns AntdError::NotImplemented (501) when caller asks for visibility:"public"
    • finalize_upload threads result.data_map_address through to the response (both wave-batch and merkle branches)
  • antd/openapi.yaml: documents the new visibility field on both prepare requests, the new data_map_address on the finalize response, the 501 case on /v1/data/prepare
  • antd/Cargo.toml: 0.6.0 → 0.6.1

Wire-compat

  • proto3-style: all new fields are Option<String> with serde-default. Old clients that don't send visibility get private behavior. New clients talking to an old daemon (pre-0.6.1) get the field silently ignored — same private behavior as before — and data_map_address will be absent in the response (the new field is omitempty).
  • The legacy store_data_map: bool field is kept and still honored so existing callers don't break. New callers should prefer visibility:"public" instead.

Test plan

  • cargo test — 26 pass (visibility serde round-trip, parser accept/reject, finalize response serialization with/without data_map_address)
  • End-to-end mainnet validation as above

Follow-ups

🤖 Generated with Claude Code

Nic-dorman and others added 2 commits May 6, 2026 17:20
Today /v1/upload/prepare unconditionally calls
file_prepare_upload(path), which is private-only. The legacy
store_data_map=true on finalize *does* publish the DataMap chunk, but
pays for it from the daemon's internal wallet — not the external
signer. Indelible needs the truly bundled atomic external-signer
public path.

This PR:

- Adds visibility: Option<String> to PrepareUploadRequest. Accepts
  "private" (default) or "public". Omitting preserves pre-0.6.x behavior.
- Switches prepare_upload to call file_prepare_upload_with_visibility,
  which is in our pinned ant-cli-v0.2.2. For "public", ant-core bundles
  the serialized DataMap as one extra chunk in the same PreparedUpload
  payment batch — the external signer signs ONE EVM tx covering chunks
  + DataMap.
- Adds the same visibility field to PrepareDataUploadRequest, but
  rejects "public" with 501 because the in-memory data path requires
  upstream data_prepare_upload_with_visibility (drafted separately as
  ant-client #73). Once that merges, the 501 flips to a real call.
- Adds data_map_address to FinalizeUploadResponse, populated from
  FileUploadResult.data_map_address when the prepared upload was public.
  Independent of the legacy store_data_map flag — that field stays
  honored for backward compat and is documented as legacy.
- Bumps antd to 0.6.1 (additive, wire-compat preserved via serde
  optional fields).
- Updates openapi.yaml for the new fields and the 501 response on
  /v1/data/prepare.

Tests cover serde round-trips for the new fields, the visibility
parser's accept/reject cases, and that data_map_address is omitted
from JSON when None (so old clients see no new fields).

Validated end-to-end on Arbitrum One mainnet: external-signer
wave-batch public upload of a 10 KB file produced 4 quotes (3 data + 1
DataMap), single payForQuotes tx covered all 4 atomically, finalize
returned data_map_address, and download_public via that address
round-tripped byte-for-byte.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI's rustfmt 1.95.0 wants the finalize tuple split across lines and the
test let-bindings collapsed onto one line; my local formatter had the
opposite preference for both. No semantic change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Nic-dorman Nic-dorman force-pushed the feat/antd-prepare-upload-visibility branch from 5148f7c to 5940534 Compare May 6, 2026 16:20
@Nic-dorman Nic-dorman merged commit a216135 into main May 6, 2026
@Nic-dorman Nic-dorman deleted the feat/antd-prepare-upload-visibility branch May 6, 2026 16:20
Nic-dorman added a commit that referenced this pull request May 6, 2026
…al-signer public uploads

Mirrors the wire shape landed in antd 0.6.1 (#57):

- New method PrepareUploadPublic(ctx, path) — POSTs visibility:"public" to
  /v1/upload/prepare. The daemon bundles the serialized DataMap as one
  extra chunk in the same PreparedUpload payment batch, so the external
  signer signs ONE EVM transaction covering chunks + DataMap.
- New field DataMapAddress on FinalizeUploadResult, populated from the
  daemon's response when the upload was prepared with visibility:"public".
- Existing PrepareUpload / FinalizeUpload signatures unchanged. Old
  daemons (pre-0.6.1) don't return data_map_address, so the new field
  is empty for callers talking to those — backward compatible.

Tests verify:
- PrepareUploadPublic actually sends visibility:"public" in the request.
- FinalizeUpload surfaces data_map_address when the daemon returns it.
- FinalizeUpload leaves DataMapAddress empty for old daemons that don't
  emit the field (wire-compat).

Requires antd >= 0.6.1 to take effect; calls against older daemons
silently degrade to the private path (the visibility field is ignored
upstream and DataMapAddress stays empty).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nic-dorman added a commit that referenced this pull request May 6, 2026
…al-signer public uploads (#58)

Mirrors the wire shape landed in antd 0.6.1 (#57):

- New method PrepareUploadPublic(ctx, path) — POSTs visibility:"public" to
  /v1/upload/prepare. The daemon bundles the serialized DataMap as one
  extra chunk in the same PreparedUpload payment batch, so the external
  signer signs ONE EVM transaction covering chunks + DataMap.
- New field DataMapAddress on FinalizeUploadResult, populated from the
  daemon's response when the upload was prepared with visibility:"public".
- Existing PrepareUpload / FinalizeUpload signatures unchanged. Old
  daemons (pre-0.6.1) don't return data_map_address, so the new field
  is empty for callers talking to those — backward compatible.

Tests verify:
- PrepareUploadPublic actually sends visibility:"public" in the request.
- FinalizeUpload surfaces data_map_address when the daemon returns it.
- FinalizeUpload leaves DataMapAddress empty for old daemons that don't
  emit the field (wire-compat).

Requires antd >= 0.6.1 to take effect; calls against older daemons
silently degrade to the private path (the visibility field is ignored
upstream and DataMapAddress stays empty).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nic-dorman added a commit that referenced this pull request May 6, 2026
Cuts v0.6.1 atop v0.6.0. Adds the public-uploads chain:

- feat(antd): wire visibility through /v1/upload/prepare (#57)
  - visibility: Option<String> on PrepareUploadRequest / PrepareDataUploadRequest
  - data_map_address: Option<String> on FinalizeUploadResponse
  - prepare_upload now calls file_prepare_upload_with_visibility — public
    prepare bundles the serialized DataMap chunk into the same external-
    signer payment batch (one EVM tx covers chunks + DataMap)
  - /v1/data/prepare returns 501 for visibility:"public" until upstream
    data_prepare_upload_with_visibility lands
- fix(antd): honor is_public on FileCostRequest (#56)
  - cost endpoint adds +1 chunk and proportional storage cost when
    is_public=true (was a no-op before)

Validated end-to-end on Arbitrum One mainnet against this dep set:
external-signer wave-batch public upload of a 10 KB file, atomic
payForQuotes for 4 quotes (3 data + 1 DataMap), finalize returned
data_map_address, /v1/files/download/public via that address round-
tripped byte-for-byte. ~0.047 ANT cost.

Same ant-core / evmlib pin as v0.6.0 (ant-cli-v0.2.2, evmlib 0.8.1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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