Skip to content

feat(opencode): treasury-funded and cross-currency reserve swaps#1085

Merged
bmc08gt merged 5 commits into
code/cashfrom
feat/opencode-treasury-cross-currency-swaps
Jul 17, 2026
Merged

feat(opencode): treasury-funded and cross-currency reserve swaps#1085
bmc08gt merged 5 commits into
code/cashfrom
feat/opencode-treasury-cross-currency-swaps

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Refreshes the opencode protobuf definitions and builds out the reserve-swap flows the server now supports, closing the gaps in the ocp service layer.

The server added treasury-funded and cross-currency reserve swaps; this wires the Android client to match — decoding the new response parameters, building the corresponding Solana transactions (signature-correct against the server handlers), and exposing request-side entry points. It also renames the two swap sealed types on StatefulSwapRequest so they stop competing for the word "kind."

What changed

Protos

  • Update opencode protobuf definitions (full_amount_exchange_data on the reserve client params; treasury / treasury_purchase_amount on the new-currency server params).

Treasury-funded new currency (create from a non-core source mint)

  • Map the new server-parameter fields into the domain model and extracted server params.
  • buildTreasuryFundedNewCurrencyBuyInstructions — mirrors the server's ReserveTreasuryFundedCreateAndBuySwapHandler (transfer source → treasury, sell for core mint into the fee destination, buy the new currency from the treasury's core-mint holdings). Dispatched from TransactionBuilder.buyNewCurrency when a treasury is present.

Cross-currency between two existing currencies

  • buildCrossCurrencyExistingSwapInstructions — mirrors the server's ReserveBuySellSwapHandler (sell the source into the core mint, then buy + deposit the destination into the user's VM). Dispatched from TransactionBuilder.swap for the new SwapRoute.CrossCurrency route.

Request-side initiation

  • crossCurrencySwap through the controller → repository → service. Branches on the destination: existing → one-time swap authority; freshly-launched stub → owner == swapAuthority + a fullAmountExchangeData valuation over the full swap + fee amount.

Rename

  • SwapStartKindSwapProgram (field kindprogram); SwapDirectionSwapRoute (field directionroute); SwapRoute.SwapSwapRoute.CrossCurrency.

Notes / follow-ups

  • For the treasury new-currency path the caller must supply fullAmountExchangeData — a USD-denominated valuation over the full swap + fee amount, keyed to the source mint. The USD-value derivation is intentionally left to where verified fiat is computed rather than fabricated in the service layer, and hasn't been validated end-to-end against the server yet.
  • The new instruction builders are covered by instrumented SwapTests (count / program / account-routing), which run in CI.

Testing

  • :services:opencode compiles (main + androidTest) and unit tests pass.
  • New instrumented tests for both instruction builders.

bmc08gt added 4 commits July 16, 2026 16:30
Adds full_amount_exchange_data to the reserve swap client parameters and
treasury/treasury_purchase_amount to the reserve new currency server
parameters for treasury-funded cross-currency swaps.

Signed-off-by: Brandon McAnsh <brandon@bmcreations.dev>
…waps

Handle the reserve new currency flow when the initial buy is funded from a
source mint other than the core mint. The full swap + fee amount is collected
into a server-controlled treasury, sold for the core mint (proceeds routed to
the fee destination), and the new currency is bought using the treasury's own
core mint holdings for a pre-coordinated amount. Mirrors the server's
ReserveTreasuryFundedCreateAndBuySwapHandler; the treasury signs the sell/buy
instructions server-side while the client signs only as the swapper.

- Map treasury/treasuryPurchaseAmount into the NewCurrency server params and
  thread them through the extracted server parameters
- Add buildTreasuryFundedNewCurrencyBuyInstructions and dispatch to it from
  TransactionBuilder.buyNewCurrency when a treasury is present
- Add the fullAmountExchangeData request field and serialize it in the reserve
  client parameters when set
- Cover the new instruction builder with count/program/account tests

Signed-off-by: Brandon McAnsh <brandon@bmcreations.dev>
StatefulSwapRequest carried two sealed types that both drifted toward the
generic word 'kind' on different axes. Give each a name for its actual axis:

- SwapStartKind (Reserve | Stablecoin) -> SwapProgram; field kind -> program
  (which on-chain program the swap runs against)
- SwapDirection (Buy | Sell | WithdrawUsdc | Swap) -> SwapRoute; field
  direction -> route (the source -> destination route)

Also rename the cross-currency route SwapRoute.Swap -> SwapRoute.CrossCurrency
to say what distinguishes it from Buy/Sell (neither side is the core mint). The
cross-currency existing currency swap path is not built client-side yet and
throws NotImplementedError.

Signed-off-by: Brandon McAnsh <brandon@bmcreations.dev>
Implement the client instruction builder for swaps between two existing
launchpad currencies (neither side the core mint), mirroring the server's
ReserveBuySellSwapHandler: transfer the source out of the user's VM swap
account into a temporary account held by the swap authority, sell it for the
core mint, then buy and deposit the destination currency into the user's
destination VM. Dispatch to it from TransactionBuilder.swap for the
SwapRoute.CrossCurrency case (previously threw NotImplementedError), and cover
the builder with count/program/account tests.

Signed-off-by: Brandon McAnsh <brandon@bmcreations.dev>
@github-actions github-actions Bot added type: feature New functionality area: crypto Solana, keys, encryption, signing area: network gRPC, connectivity, API, exchange rates area: intents Intent construction, submission, server-side state and removed type: feature New functionality labels Jul 16, 2026
Expose a crossCurrencySwap entry point through the controller, repository and
service that swaps one launchpad currency directly for another. It builds a
Reserve stateful swap with a SwapRoute.CrossCurrency route and branches on the
destination:

- existing destination -> one-time swap authority; server returns existing
  currency parameters (buy+sell handler)
- freshly-launched stub destination -> owner == swap authority and a
  fullAmountExchangeData valuation over the full swap + fee amount; server
  returns treasury-funded new currency parameters

The response builders for both paths already exist, so this closes the
request-side gap. The caller supplies fullAmountExchangeData (USD-valued,
keyed to the source mint) for the new-currency case.

Signed-off-by: Brandon McAnsh <brandon@bmcreations.dev>
@bmc08gt
bmc08gt force-pushed the feat/opencode-treasury-cross-currency-swaps branch from 0868486 to 1557e5e Compare July 17, 2026 16:54
@github-actions github-actions Bot added the type: feature New functionality label Jul 17, 2026
@bmc08gt
bmc08gt merged commit 7173402 into code/cash Jul 17, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the feat/opencode-treasury-cross-currency-swaps branch July 17, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: crypto Solana, keys, encryption, signing area: intents Intent construction, submission, server-side state area: network gRPC, connectivity, API, exchange rates type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant