Skip to main content
Confiroll vendors the Stellar Disbursement Platform (SDP) v6.6.1 (Apache-2.0) and runs it headless. Confiroll does not use it as a disbursement platform, and never calls SDP’s disbursement/HTTP payout API. Confiroll uses it purely as reliable submission infrastructure.

What Confiroll uses SDP for

Channel-account pool

A pool of pre-provisioned channel accounts that source outbound transactions (bootstrapped with channel-accounts ensure).

Fee-bump

SDP’s transaction worker wraps a queued operation with a channel-account inner tx and fee-bumps it from the distribution account.

Submit

Simulates against RPC, applies Soroban resources, and submits.

Retry

The worker loop retries on transient failures.
The commands Confiroll relies on are the worker (tss), channel-accounts (create/ensure/verify/view/delete), and serve (the headless HTTP surface for health/toml). Confiroll leaves the disbursement, receiver, and payment flows of stock SDP unused.
Two commands run the moving parts. channel-accounts ensure provisions the pool of source accounts, and tss runs the worker that drains the queue and fee-bumps:

Why not the HTTP API

SDP’s HTTP sponsored-transaction endpoint derives the sponsored account from the caller’s passkey, so it can only sponsor an SDP embedded smart wallet, with no field for an employer’s G-address. A confidential payout is sourced by a classic account, so the HTTP API simply cannot express it. Because of this, Confiroll’s relay bypasses the HTTP API and writes directly into SDP’s Postgres queue.

The relay: writing straight to the queue

  • It inserts a PENDING, SPONSORED-type row into tss.submitter_transactions (carrying the external id, tenant, sponsored account, sponsored operation XDR, and distribution account) via a pg client.
  • SDP’s unmodified TSS worker picks up the row and does the channel-source + distribution-fee fee-bump, simulate, submit, retry.
  • The relay holds no keys and signs nothing.
The same flow, step by step:
1

Insert a queued row

The relay’s pg client inserts one PENDING, SPONSORED-type row into tss.submitter_transactions, carrying the external id, tenant, sponsored account, sponsored operation XDR, and distribution account. No key is used and nothing is signed here.
2

Worker claims it

SDP’s unmodified TSS worker polls the table and claims the pending row.
3

Fee-bump from a channel account

The worker sources the operation on a channel account from the pool and builds a CAP-15 fee-bump paid by the distribution account.
4

Simulate, submit

It simulates against RPC, applies Soroban resources, and submits.
5

Retry on transient failure

The worker loop retries transient failures until the transaction reaches a terminal state.

Environment

The relay and worker are configured entirely through environment variables:
This queue-relay path powers the batch flow (/batch). The deployed, non-custodial write path for real payouts is Fork B /transfer, which fee-bumps a browser-signed transfer directly through the API sponsor, not through SDP. See Fee sponsorship.

The one upstream modification

Confiroll keeps SDP as close to upstream as possible. The single code change is in the TSS handler internal/transactionsubmission/sponsored_transaction_handler.go: Stock SDP validates the sponsored principal as a contract (C-) address only. Its “embedded wallet” feature assumes a Soroban smart-wallet principal. Confiroll’s confidential payroll relays operations authorized by classic accounts too, so the patch widens that one validation to also accept a valid ed25519 (G-) address:
The rest of the handler is unchanged upstream logic. It still rejects ops requiring auth from the channel or distribution account, re-sources the op to the distribution account, and builds on a channel-account sequence. The vendored copy records the change in its MODIFICATIONS.md and retains the upstream LICENSE (Apache-2.0). The vendored tree trims tests, CloudFormation, and the Helm chart.
Everything provisioned on the SDP side (channel accounts, the tenant, the distribution account) is operational infrastructure. None of it can read a confidential amount or spend a user’s balance; those depend on keys SDP never holds.

FAQ

SDP’s HTTP sponsored-transaction endpoint derives the sponsored account from the caller’s passkey, so it only ever sponsors an SDP embedded smart wallet and has no field for an employer’s G-address. A confidential payout is sourced by a classic account, so the relay inserts a PENDING, SPONSORED-type row straight into tss.submitter_transactions and lets the unmodified worker fee-bump it.
One handler. The single change is in internal/transactionsubmission/sponsored_transaction_handler.go, widening the sponsored principal check to accept an ed25519 (G-) address as well as a contract (C-) address. Everything else is stock SDP v6.6.1 (Apache-2.0); the vendored copy records the diff in MODIFICATIONS.md and keeps the upstream LICENSE.
No. The queue relay powers the batch flow (/batch). Real non-custodial payouts go through Fork B POST /transfer, where the API sponsor fee-bumps a browser-signed transfer directly. See fee sponsorship.