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.
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’sG-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 intotss.submitter_transactions(carrying the external id, tenant, sponsored account, sponsored operation XDR, and distribution account) via apgclient. - 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.
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 handlerinternal/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:
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
Why write to the database instead of calling SDP's API?
Why write to the database instead of calling SDP's API?
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.How far does Confiroll diverge from upstream SDP?
How far does Confiroll diverge from upstream SDP?
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.Is the SDP relay the path real payouts take?
Is the SDP relay the path real payouts take?
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.