Skip to content

feat(antd-js): 07-external-signer example (V2-312, 2/15)#99

Merged
Nic-dorman merged 1 commit into
mainfrom
nic/v2-312-antd-js-07-external-signer
May 19, 2026
Merged

feat(antd-js): 07-external-signer example (V2-312, 2/15)#99
Nic-dorman merged 1 commit into
mainfrom
nic/v2-312-antd-js-07-external-signer

Conversation

@Nic-dorman
Copy link
Copy Markdown
Collaborator

Second of 15 SDK examples for V2-312. antd-js is the canonical TypeScript reference; the remaining 13 SDKs follow.

What this adds

  • antd-js/examples/07-external-signer.ts — TypeScript example exercising both V2-312 flows end-to-end using ethers v6
  • antd-js/package.json — adds ethers ^6.13 as a devDependency (no other web3 deps in the package; pulled in only for the example)
  • ant-dev/src/ant_dev/cmd_example.py — adds external_signer to the js adapter
  • antd-py/examples/07_external_signer.py — empty-payments short-circuit fix (mirrored across both examples for consistency)

Validation

Validated against ant dev start --enable-evm on dev2:

File prepare: uploadId=540eeecaca82d211…, paymentType=wave_batch, payments=4, totalAmount=59187152343750000
File finalize: dataMapAddress=c135f334e76f7faf622f514e3e76727eb9e2f11b9023598b9caec4c5e566c8a6, chunksStored=4
File round-trip OK!
Chunk prepare: uploadId=0c5566df90247030…, address=c5c96c8a00aa4be6a1aa7ff59f4f569a704322942ca4fd5e02dce7212d53cb06, payments=1, totalAmount=14826855468750000
Chunk finalize: address=c5c96c8a00aa4be6a1aa7ff59f4f569a704322942ca4fd5e02dce7212d53cb06
Chunk round-trip OK!

07-external-signer OK!

Patterns for the remaining 13 SDKs

Validation surfaced two gotchas worth flagging up-front:

  1. Per-language distinct content. Use hello external signer from <lang> so each SDK exercises a fresh payment flow on a shared anvil instance. Otherwise the daemon's prepare step elides zero-amount entries (chunks already-stored) and the example never gets to exercise the payment surface.

  2. Empty-payments short-circuit. if (prep.payments.length === 0) return {} — handles the already-stored case generally. Daemon accepts empty tx_hashes for finalize. Worth replicating across all 14 SDK examples.

  3. Nonce management. ethers v6 needs NonceManager to avoid stale-nonce races on back-to-back contract calls; provider.getTransactionCount can lag even after await tx.wait(). web3.py handles it implicitly via explicit nonce= per build_transaction. SDKs using other libs (web3j, Nethereum, alloy, etc.) will need to check their library's idiom — flagging as a likely papercut.

Closes 2/15 of V2-312.

…x (V2-312, 2/15)

Mirrors antd-py's 07_external_signer in TypeScript using ethers v6. Both
flows validated end-to-end against ant dev start --enable-evm on dev2:
  File:  4 payments, dataMapAddress=c135f334...
  Chunk: 1 payment, address=c5c96c8a...

Notable patterns for the 14 SDKs to follow:

  1. Per-language distinct file/chunk content ("hello external signer from
     js (file)" vs antd-py's "... (file)"). When the chain has been used
     for a prior SDK's validation run, the same content hashes to chunks
     already on-network and prep returns empty payments. Distinct content
     forces a fresh payment flow.

  2. Empty-payments short-circuit: `if (prep.payments.length === 0) return {}`
     (mirrored in antd-py for consistency). The daemon's prepare elides
     zero-amount entries when chunks are already-stored; finalize accepts
     an empty tx_hashes dict.

  3. NonceManager wrapper for ethers v6 — provider.getTransactionCount can
     lag across back-to-back txs even after await tx.wait(). NonceManager
     tracks locally, no provider round-trip per call.

Adds ethers ^6.13 as a devDependency of antd-js (no other web3 deps in the
package; pulled in only for the example).

Also adds the js adapter's `external_signer` short-name to ant-dev's
example dispatcher.
@Nic-dorman Nic-dorman merged commit 739b846 into main May 19, 2026
Nic-dorman added a commit that referenced this pull request May 21, 2026
Cuts v0.8.0 atop v0.7.1. Substantial breaking-change roll-up of the
put/get rename, the private-file PUT/GET gap close, and several minor
surface cleanups -- bundled here so the v1.0 cut can ship stable on top.

## Breaking (antd daemon)

- feat(antd)!: bind to 127.0.0.1 by default on REST and gRPC (#107).
  Previously bound 0.0.0.0; use --bind-rest / --bind-grpc to override.
- chore: remove dead graph_entry surface from antd proto + 5 SDKs (#92).
  GraphService and its 4 RPCs are gone; REST mounts dropped.
- chore: remove dir_upload_public / dir_download_public surface (#95).
  Use file_put_public on a directory path instead; the daemon recurses.
- feat(antd)!: normalize put/get convention + close private-file PUT and
  GET gaps (#115). Method renames across proto + REST + SDKs:
    data_put_private    -> data_put
    data_get_private    -> data_get
    file_upload_public  -> file_put_public
    file_download_public -> file_get_public
  New: file_put / file_get for the private file path (previously only
  the public variant existed). New typed results: DataPutResult,
  DataPutPublicResult, FilePutResult, FilePutPublicResult; PutResult
  is now annotated as chunk_put only.

## Additive

- feat(antd): honor payment_mode on gRPC put/cost paths and REST cost
  endpoints (#114). Optional kwarg threaded through every put/cost
  signature; empty/omitted maps to "auto" so older clients keep working.
- feat: external-signer public uploads + single-chunk prepare/finalize
  across 15 SDKs (#90).
- docs+spec: openapi.yaml refreshed for the v1.0 surface, including
  POST /v1/chunks/prepare and /v1/chunks/finalize for single-chunk
  external-signer publish (#126).

## SDK fan-out (PaymentMode + put/get convention, all 15)

#116 antd-go, #117 antd-py/ruby/elixir, #118 antd-rust, #119 antd-csharp,
#120 antd-java, #121 antd-swift, #122 antd-dart, #123 antd-kotlin,
#124 antd-cpp, #125 antd-js/php/zig/lua, #127 antd-mcp.

## SDK example + build fixes

- fix(antd-go): make 03-files example self-contained and runnable (#91)
- fix(examples): make 04-files runnable across cpp/rust/elixir/lua/php/ruby/zig (#93)
- fix(examples): runnable dart 04_files + java Example03Files; add java Example03Chunks (#94)
- feat: gRPC transport example for antd-py and antd-rust (#113)
- feat(antd-py): 07_external_signer example + ant-dev dispatcher entry (#98)
- feat(antd-js): 07-external-signer example + antd-py empty-payments fix (#99)
- feat(rust/go): 07-external-signer examples (#100)
- feat(antd-csharp): 07_external_signer example (#101)
- feat(antd-java): 07_external_signer example (#102)
- feat(antd-kotlin): 07_external_signer example (#103)
- feat(antd-dart): 07_external_signer example (#104)
- feat(antd-ruby): 07_external_signer example (#105)
- feat(antd-php): 07_external_signer example (#106)
- chore(antd-kotlin): drop stale GraphDescendant from local proto copy (#108)

## Docs / infra

- docs: external-signer flow reference + ABI + python smoke test (#97)
- docs: add SECURITY.md with threat model and disclosure policy (#109)
- docs!: refresh per-SDK READMEs + llms-full.txt + openapi.yaml for v1.0 surface (#126)
- ci: add Go lint + test + vuln scanning for antd-go (#112)
- ci: extend antd-rust to sibling-repo parity (fmt + clippy + audit + doc) (#111)
- ci: skip antd/openapi.yaml and llms-full.txt from triggering CI (#128)
- chore(scripts): add full-stack + integration sweep helpers (#96)
- fix(antd-rust): regenerate Cargo.lock to unbreak --locked CI (#110)

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