Skip to content

WIP: mailbox round/OOR plumbing + toy SDK e2e surface - #130

Closed
bhandras wants to merge 1 commit into
arktest-sdk-e2efrom
codex/e2e-two-client-join-oor-client
Closed

WIP: mailbox round/OOR plumbing + toy SDK e2e surface#130
bhandras wants to merge 1 commit into
arktest-sdk-e2efrom
codex/e2e-two-client-join-oor-client

Conversation

@bhandras

@bhandras bhandras commented Feb 26, 2026

Copy link
Copy Markdown
Member

Summary

This draft introduces a toy SDK + mailbox plumbing path in darepo-client that is sufficient to drive a real end-to-end demo in systest.

The intent is to prove integration shape (round join + OOR send + incoming sync) with real mailbox transport and actor wiring, not to claim production-complete SDK semantics.

Detailed Changes

1) Mailbox wire payload layer for round/OOR

  • Add round mailbox payload schema and codecs (roundwire).
  • Add OOR mailbox payload schema and codecs (oorwire).
  • Keep mailbox envelope transport in protobuf while method payloads are currently JSON-encoded for rapid iteration.

2) Runtime dispatch and actor bridging

  • Add round mailbox dispatchers + codec mappings so inbound envelopes are mapped to existing round actor messages.
  • Add OOR mailbox outbox handler that executes OOR FSM side effects via mailbox unary RPC (SubmitPackage/FinalizePackage).
  • Update serverconn/darepod dispatch integration to route inbound round notifications into the local actor system.

3) Toy SDK surface for e2e plumbing

  • Add sdk/client.go with a high-level API for:
    • requesting round outputs,
    • triggering round join,
    • deriving recipient addresses,
    • sending OOR payment,
    • syncing incoming OOR transfers,
    • listing live balance and live VTXOs.
  • Hide envelope-level plumbing from SDK consumers; keep lower-level controls in config.

4) Tests

  • Add address-focused SDK tests (sdk/address_test.go).
  • Update round outbox tests for new mailbox payload behavior.

Why Draft / Incomplete

This branch intentionally optimizes for proving full plumbing quickly. It is not yet the final API/contract boundary.

Missing For Completeness

  • Recipient ownership/auth proof model for receive addresses and incoming claims.
  • Stronger replay/idempotency guarantees across crashes/restarts.
  • Hardened SDK error taxonomy + retry/backoff semantics.
  • Stable protobuf message contracts for all mailbox method payloads.
  • Full operator/client API parity beyond current round/OOR-focused path.
  • Wider chaos/fault/concurrency test matrix.

Builds On

Validation

  • make lint
  • go test ./sdk

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @bhandras, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes a foundational embedded SDK for the Ark protocol, primarily aimed at facilitating system tests. It integrates core Ark functionalities such as round participation, out-of-round transfers, and VTXO state management through a mailbox-based RPC transport. The changes introduce a new client daemon (darepod) and a comprehensive IndexerService to manage and query VTXO lifecycle events, enabling robust end-to-end testing of the Ark client-operator interaction.

Highlights

  • Embedded SDK Path: A toy embedded SDK path has been wired through real mailbox transport to enable systests for various Ark functionalities.
  • Round Functionality: The PR introduces plumbing for round output registration, join triggers, and server/client mailbox message exchange.
  • Out-of-Round (OOR) Transfers: Support for OOR submit/finalize over mailbox unary RPC and receive-address based OOR targeting has been added.
  • VTXO Management: Incoming transfer synchronization and materialization, along with live balance and VTXO listing for pre/post assertions, are now supported.
  • New Daemon (darepod): A new client daemon, darepod, has been introduced with its own gRPC API for wallet operations and integration with lnd and the Ark operator.
  • Indexer Service: A new IndexerService and client have been added, providing RPCs for receive script management, VTXO listing, subtree retrieval, and event feeds, with proof-of-control mechanisms.
  • LND Integration: An lndbackend adapter has been implemented to integrate lndclient's remote signing interfaces with the round.ClientWallet for MuSig2 operations.
  • Mailbox RPC Payloads: New wire-format payloads (oorwire and roundwire) have been defined for OOR and round-related mailbox RPCs, ensuring structured communication between client and server.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .gitignore
    • Added bin/darepod to the ignore list.
  • Makefile
    • Updated build and install targets to include the new darepod binary.
  • arkrpc/ark.pb.go
    • Extended GetInfoResponse with new operator configuration fields and their getter methods.
  • arkrpc/ark.proto
    • Expanded GetInfoResponse message with additional operator terms such as exit delays, forfeit script, sweep key, dust limits, and fee rates.
  • arkrpc/indexer.pb.go
    • Generated Go code for the new IndexerService protobuf definitions, including VTXO status, event types, and various request/response messages for indexing operations.
  • arkrpc/indexer.proto
    • Defined the new IndexerService for VTXO and OOR event management, including RPCs for registering/unregistering receive scripts, listing VTXOs, retrieving subtrees, and event feeds.
  • arkrpc/indexer_grpc.pb.go
    • Generated gRPC client and server interfaces for the IndexerService.
  • arkrpc/indexer_mailboxrpc.pb.go
    • Generated mailbox RPC client and server interfaces for the IndexerService.
  • cmd/darepod/main.go
    • Added the main entry point for the darepod client daemon, including CLI argument parsing with cobra and viper, and daemon startup logic.
  • daemonrpc/daemon.pb.go
    • Generated Go code for the new DaemonService protobuf definitions, including GetInfoRequest and GetInfoResponse with detailed daemon and server information.
  • daemonrpc/daemon.proto
    • Defined the new DaemonService for daemon status information, including version, network, lnd connection state, and Ark server terms.
  • daemonrpc/daemon_grpc.pb.go
    • Generated gRPC client and server interfaces for the DaemonService.
  • daemonrpc/daemon_mailboxrpc.pb.go
    • Generated mailbox RPC client and server interfaces for the DaemonService.
  • darepod/config.go
    • Defined configuration structures and default values for the darepod daemon, covering data directories, network, lnd connection, Ark server, and RPC settings.
  • darepod/log.go
    • Implemented logging utilities for the darepod package, integrating with btclog.
  • darepod/rpc_server.go
    • Implemented the DaemonService gRPC server for darepod, providing daemon status information.
  • darepod/server.go
    • Implemented the core darepod server logic, orchestrating lnd connection, mailbox transport, actor system, database, and RPC services, including fetching operator terms.
  • go.mod
    • Added new dependencies github.com/spf13/cobra and github.com/spf13/viper.
  • go.sum
    • Updated module checksums to reflect new dependencies.
  • indexer/client.go
    • Implemented a client wrapper for IndexerService with proof generation logic for receive script registrations and script-scoped queries, using TLV encoding and BIP-340 schnorr signatures.
  • indexer/nonce.go
    • Added a utility function for generating cryptographically secure random nonces.
  • indexer/sync_client.go
    • Implemented a cursor-aware client for syncing VTXO and OOR recipient events, ensuring monotonic cursor persistence.
  • indexer/sync_client_test.go
    • Added tests for the SyncClient and MemorySyncCursorStore to verify cursor persistence and monotonic behavior.
  • lndbackend/client_wallet.go
    • Implemented an adapter for lndclient's remote signing interfaces to the round.ClientWallet interface, supporting ECDSA and Schnorr signatures, and MuSig2 session management.
  • oor/mailbox_outbox_handler.go
    • Implemented the OutboxHandler for the OOR FSM, using mailbox RPC for submitting and finalizing packages, and handling checkpoint signatures.
  • oorwire/payloads.go
    • Defined wire-format payloads for OOR mailbox RPCs, including SubmitPackage and FinalizePackage requests and responses, with JSON encoding for PSBTs and signing descriptors.
  • round/mailbox_codec.go
    • Implemented decoding logic for server mailbox payloads into client round FSM events, handling various roundwire message types.
  • round/mailbox_dispatchers.go
    • Provided serverconn dispatchers for server-to-client round EVENT envelopes, routing incoming messages to the appropriate round actor.
  • round/outbox_messages.go
    • Updated ToProto methods for JoinRoundRequest, SubmitNoncesRequest, SubmitPartialSigRequest, and SubmitForfeitSigRequest to use new roundwire payloads and RPC service/method definitions, including serialization logic.
  • round/outbox_messages_test.go
    • Updated tests for ToProto methods to check for non-nil protobuf messages, reflecting the new serialization logic.
  • roundwire/payloads.go
    • Defined wire-format payloads for round mailbox RPCs, including client requests (JoinRound, SubmitNonces, SubmitPartialSigs, SubmitForfeitSigs, SubmitVTXOForfeitSigs) and server responses (ClientErrorResp, ClientSuccessResp, ClientBatchInfo, etc.), with helper functions for encoding/decoding various Bitcoin primitives.
  • scripts/gen_protos.sh
    • Updated the proto generation script to include daemonrpc.
  • sdk/address_test.go
    • Added tests for encoding and decoding receive addresses, including validation for unsupported versions.
  • sdk/client.go
    • Implemented a high-level embedded SDK client for Ark, managing OOR transfers, VTXO state, and receive addresses, including logic for NewReceiveAddress, SyncIncoming, and SendOORPayment.
Activity
  • This pull request is a work in progress, serving as a draft to demonstrate the end-to-end plumbing for systests.
  • The author explicitly states that the goal is to show the plumbing shape, not production-complete SDK semantics, and highlights missing features for completeness.
  • The PR builds upon several other related issues and pull requests in darepo and darepo-client repositories.
  • Validation steps include make lint and go test ./sdk.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant set of changes to wire up end-to-end functionality for mailbox-based rounds and out-of-round (OOR) payments, including a new darepod daemon and a toy SDK. The changes are extensive, adding new protobuf definitions for arkrpc, indexer, and daemonrpc, along with their corresponding generated Go code. The PR also introduces new wire formats for OOR and round messages, a client for the indexer service, and a high-level SDK client. The overall structure is well-organized, with clear separation of concerns between the daemon, RPC services, and the SDK. The use of cobra and viper for the new daemon is a good choice. The mailbox transport logic is extended to support routed events, which is a key piece of the new plumbing. My review found one minor issue regarding error handling in the new daemon's main command file.

Comment thread cmd/darepod/main.go
v.SetEnvPrefix("DAREPOD")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.AutomaticEnv()
_ = v.BindPFlags(f)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The error returned by v.BindPFlags is being ignored. While an error is unlikely here (it seems to only error if the flag set is nil), it's a best practice to handle all returned errors for robustness. A panic with a descriptive message would be appropriate for such an unrecoverable setup error.

Suggested change
_ = v.BindPFlags(f)
if err := v.BindPFlags(f); err != nil {
panic(fmt.Errorf("error binding pflags: %w", err))
}

@bhandras
bhandras force-pushed the codex/e2e-two-client-join-oor-client branch 3 times, most recently from 0efdd12 to 42818df Compare February 27, 2026 05:22
@bhandras
bhandras changed the base branch from main to arktest-sdk-e2e February 27, 2026 05:24
@bhandras
bhandras force-pushed the codex/e2e-two-client-join-oor-client branch 4 times, most recently from 79074d3 to 19c8951 Compare February 27, 2026 09:15
This commit introduces the client/runtime-side plumbing needed to run a real
mailbox-backed round+OOR flow and expose it through a minimal SDK surface that
systests can drive end-to-end.

What is added:
- Round mailbox wire protocol:
  - add `roundwire` payload schema/serialization for round request/response and
    server event envelopes.
  - add round mailbox codec + dispatchers to convert mailbox envelopes to
    existing round actor messages and vice versa.
- OOR mailbox wire protocol:
  - add `oorwire` payload schema/serialization for submit/finalize package RPCs.
  - add mailbox outbox handler for OOR FSM side effects (submit, finalize,
    checkpoint-signing follow-through, and local spend marking).
- Connector/runtime wiring:
  - extend `serverconn` actor/runtime dispatch integration so inbound mailbox
    round notifications are routed into the client round actor cleanly.
  - update `darepod/server` dispatch map construction for mailbox request/event
    handling through the existing actor system.
- Toy SDK layer for e2e demonstration:
  - add `sdk/client.go` with a high-level API for round output request/join,
    recipient address generation, OOR send, incoming sync/materialization, and
    live balance/VTXO listing.
  - hide mailbox envelope plumbing from SDK consumers; keep advanced knobs at
    config boundaries.
- Harness CI stability hardening:
  - extend container startup retry behavior to also retry transient image pull
    failures (e.g. registry "unknown blob") in addition to port bind conflicts.
  - add targeted unit tests for image-pull error detection and retry behavior.
- Tests:
  - add SDK receive address tests and update round outbox tests to cover new
    mailbox payload encode/decode paths.

Notes:
- This is intentionally an incomplete/"toy" SDK path aimed at validating e2e
  plumbing shape.
- Includes lint-driven cleanup in touched files.
@bhandras
bhandras force-pushed the codex/e2e-two-client-join-oor-client branch from 19c8951 to 3c58148 Compare February 27, 2026 09:21
Comment thread sdk/client.go
return err
}

startResp := c.oorActor.Receive(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should send the message rather than calling Receive directly (so hook up the actual actor system).

}

rpcClient := h.oorRPCClient()
resp, err := rpcClient.FinalizePackage(ctx, req)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should purely go through serverconn?

Comment thread roundwire/roundwire.proto
}

message JoinRoundAuthPayload {
string message_hex = 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we just make this bytes, then we don't need the hex encode/decode portions in oorwire or roundwire. Then we just have that map to/from protos.

@Roasbeef

Roasbeef commented Mar 6, 2026

Copy link
Copy Markdown
Member

Great example here of hooking everything up, will incorporate the commits into #142.

@Roasbeef

Roasbeef commented Mar 7, 2026

Copy link
Copy Markdown
Member

Integrated more of the commits from this PR into: #144

Main thing remaining is the sdk client wrapper itself.

@bhandras

Copy link
Copy Markdown
Member Author

Closing this as it is now superseded by production plumbing.

@bhandras bhandras closed this Mar 23, 2026
@bhandras
bhandras deleted the codex/e2e-two-client-join-oor-client branch March 23, 2026 15:18
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.

2 participants