Skip to content

feat(android-demo): external-signer paid uploads via WalletConnect [blocked on ant-sdk release]#1

Closed
Nic-dorman wants to merge 9 commits into
mainfrom
spike/android-walletconnect
Closed

feat(android-demo): external-signer paid uploads via WalletConnect [blocked on ant-sdk release]#1
Nic-dorman wants to merge 9 commits into
mainfrom
spike/android-walletconnect

Conversation

@Nic-dorman

Copy link
Copy Markdown

Draft — blocked on an ant-sdk release. Depends on WithAutonomi/ant-sdk#199 (external-signer FFI + progress callbacks). The demo consumes the new surface via the release AAR; this PR builds once that AAR is published. The local app/libs/ant-android-release.aar is now gitignored (was wrongly tracked, 27MB) — it ships via the SDK release.

What

AntAndroidDemo consumer app for the external-signer paid-upload flow: the app builds the ERC-20 calldata (approve + payForQuotes) and the user's self-custody wallet (WalletConnect/Reown AppKit) signs — no embedded key. Mirrors the desktop ant-ui flow.

connect→sign verified end-to-end on a real Galaxy S10 (Android 12): MetaMask session approved, eth_sendTransaction signed, tx confirmed on-chain (receipt status 0x1).

Changes

  • Two-step quote→approve upload with a cost/visibility confirm dialog
  • Real per-stage % progress via the FFI ProgressListener callback
  • Public/Private visibility; Private saves a re-downloadable datamap
  • Downloads: one field + attach-datamap + Download (autonomi:// link or datamap file)
  • approve→confirm receipt-poll (waitForReceipt); explicit gas fields on sendTransaction
  • autonomi:// deep links (AntUri); first-sign relay warm-up auto-retry

Notes

  • Stops tracking app/libs/ant-android-release.aar — ships via the SDK release, gitignored.
  • Background transfers are foreground-only for now (see Linear V2-563: foreground-service).

🤖 Generated with Claude Code

Nic and others added 9 commits June 24, 2026 14:13
Kotlin counterpart of the iOS spike. Connect an external wallet (Reown
AppKit Android) and have it sign a real eth_sendTransaction — an ERC-20
approve of the Autonomi payment vault (amount 0 → gas only). On a
physical device this completes the signature end-to-end.

- app/build.gradle.kts: com.reown:android-bom:1.4.1 + core + appkit
- wallet/EthCalldata.kt: approve + payForQuotes (BigInteger)
- wallet/AutonomiContracts.kt: Arbitrum chains + token/vault addrs
- wallet/WalletConnectManager.kt: init/chains/ModalDelegate/request
- MainActivity/MainScreen: configure + Compose wallet UI + modal
- AndroidManifest: antdemo-wc:// deep-link return scheme
- README: spike section + known unknowns

Reown Android API written against docs; verify in Studio. Not a full
paid upload (needs ant-ffi external-signer surface, V2-391).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Get AntAndroidDemo building with the WalletConnect spike:

- Add Gradle 8.9 wrapper (system Gradle 9.5.1 is incompatible with AGP 8.5.2)
- settings.gradle.kts: add JitPack repo (Reown pulls Scarlet, kethereum,
  custom-qr-generator, multiformats from there)
- build.gradle.kts: material-navigation:1.7.6 (bottom-sheet navigator the
  AppKit modal host needs; not in the Compose BOM)
- Correct the Reown AppKit Android API against the resolved appkit:1.4.1
  (javap) + upstream sample/modal:
  - CoreClient.initialize + AppKit.initialize + setChains from presets
  - full 14-method ModalDelegate; response via onSessionRequestResponse
  - getAccount().address/.chain; AppKit.request(Request(method,params),..)
  - Compose modal is NavHost + appKitGraph + Web3Button (no AppKitComponent);
    added AppRoot() hosting a bottom-sheet NavHost

BUILD SUCCESSFUL — debug APK (arm64-v8a incl.) assembles. Still needs a
Reown projectId in MainActivity and a physical device to run the
connect -> sign round-trip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Runtime crash on launch: appkit 1.4.1's `appKitGraph` presents the modal
via Accompanist's navigation-material `bottomSheet {}`, but the NavHost had
registered the newer androidx material-navigation BottomSheetNavigator →
"Could not find Navigator with name BottomSheetNavigator". (appkit's
`develop` sample uses androidx; the 1.4.1 release still uses Accompanist.)

Swap to accompanist-navigation-material:0.34.0 (the version appkit pulls)
and use rememberBottomSheetNavigator + its ModalBottomSheetLayout.

Verified on a physical Galaxy S10 (Android 12) over wireless adb: app
launches, full UI renders, Reown "Connect wallet" (Web3Button) shown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on device

Swap the temporary borrowed projectId for a dedicated mobile-SDK Reown
projectId (public client identifier).

Verified end-to-end on a physical Galaxy S10 (Android 12) over wireless adb:
Connect wallet -> MetaMask approves session (account 0xc2..8691, chain
eip155:42161 Arbitrum One) -> "Send test approve tx" -> MetaMask signs
eth_sendTransaction -> app receives tx hash. Confirmed on-chain (Arbitrum
One): ERC-20 approve(paymentVault, 0) on the ANT token, receipt status 0x1.

This proves the external-signer flow (app builds calldata, external wallet
signs, no embedded key) works on mobile — the store-policy-safe payment model.

Note: the "Batch subscribe timed out" status is a benign Reown relay
background timeout surfaced by Delegate.onError; not a tx failure. Follow-up
polish: don't route relay-internal errors to the user-facing status line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s + dark mode

Rework AntAndroidDemo into a faithful facsimile of the desktop app (ant-ui):

- Autonomi palette as Material3 dark+light schemes (ui/Theme.kt), lifted from
  ant-ui tailwind.config.cjs + main.css. ThemeController persists the choice.
- Bottom navigation (mobile pattern): Uploads · Downloads · Wallet · Settings.
  Nodes intentionally omitted — nodes can't run on mobile.
- Files split into two tabs (Uploads / Downloads) given limited screen width;
  rows mirror files.vue (name · status badge · size · cost · date, progress,
  mono address, saved-to). Wired to real dataPutPublic/dataGetPublic; seeded
  with mock rows so the lists look lived-in.
- Wallet screen: external-signer connect (Web3Button) + payment test + mock
  balances.
- Settings screen: bordered cards mirroring settings.vue; the Light Mode
  toggle is live (drives ThemeController, persisted); other cards are mock.

Verified on a physical S10: all tabs render in both dark and light; the
dark-mode toggle swaps the whole app live and survives relaunch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… settings

- Replace the Light Mode toggle with a "Screen mode" segmented control
  (Dark | Light), left=Dark right=Light, reflecting/driving ThemeController.
- Remove Settings cards that don't apply on mobile: Storage Directory,
  Downloads Directory (not user-settable), and the Node daemon version in
  About (no daemon on mobile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump the bundled AAR to the external-signer surface and route uploads through
it when a wallet is connected:

- FilesStore.upload: if a WalletConnect wallet is connected, run
  prepare_data_upload → wallet signs approve + payForQuotes (via
  WalletConnectManager.sendTransaction + EthCalldata) → finalize_upload,
  driving the Quoting → AwaitingApproval → Paying → Uploading → Complete
  states. Falls back to the devnet single-shot dataPutPublic otherwise.
- EVM token/vault addresses for the calldata are read from the on-device
  devnet manifest (parseManifestEvm).
- WalletConnectManager: generalized to sendTransaction(to, data); sendApprove
  now delegates to it.
- app/libs/ant-android-release.aar: rebuilt from ant-sdk feat/ffi-external-signer.

Compiles + launches on the S10. NOTE: completing the payment on-chain requires
the connected wallet to be on the same chain as the devnet payment vault
(MetaMask-on-Arbitrum vs local Anvil) and a reachable devnet — documented
caveats; not yet run end-to-end.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…igner client

- autonomi:// deep-link support: AntUri parser ports ant-webex's parseAntUri /
  buildFilename / sanitizeFilename (name + filetype → name.filetype, address-
  derived fallback), plus an explicit `filename` param override. VIEW intent on
  the autonomi scheme → download the address (with the resolved filename) and
  jump to the Downloads tab (singleTask + onNewIntent + DeepLinkNav bus).
- External-signer uploads now use the wallet-free
  connectFromDevnetManifestExternalSigner (works with the Sepolia devnet).
- FilesStore.download accepts a suggested filename (deep-link supplied).
- Bump bundled AAR to latest ant-core (0.2.9) build.

Verified on the S10: firing autonomi://<addr>?name=quarterly-report&filetype=pdf
opens the app, shows Downloads with a "quarterly-report.pdf" row, and starts the
fetch (fails only when no devnet manifest is present).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AntAndroidDemo consumer app for the external-signer flow (app builds
calldata, user's self-custody wallet signs — no embedded key). Verified
connect→sign end-to-end on a real Galaxy S10:

- two-step quote→approve upload with a cost/visibility confirm dialog
- real per-stage % progress via the FFI ProgressListener callback
- Public/Private visibility; Private saves a re-downloadable datamap
- Downloads: one field + attach-datamap + Download (autonomi:// or datamap)
- approve→confirm receipt-poll; explicit gas fields on sendTransaction
- autonomi:// deep links (AntUri); first-sign relay warm-up auto-retry

Consumes new ant-ffi surface from ant-sdk #199 (via the release AAR).
Stops tracking app/libs/ant-android-release.aar (27MB) — ships via the
ant-sdk release, gitignored. Blocked on that release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Nic-dorman

Copy link
Copy Markdown
Author

Superseded — the demo app moved to its own repo: WithAutonomi/ant-mobile-android, which consumes com.autonomi:ant-android:0.0.3 from the ant-maven Pages Maven repo rather than a bundled libs/*.aar. Builds green against it. ant-android is now a pure SDK-distribution repo.

@Nic-dorman Nic-dorman closed this Jul 7, 2026
@Nic-dorman Nic-dorman deleted the spike/android-walletconnect branch July 7, 2026 08:30
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