Satsails app icon

Self-custody · Bitcoin, Liquid, DePix

What it takes to pull a Satsails balance, history, and DePix flow

Where a Satsails balance actually lives

Because the signing keys stay on the phone, the spendable balance of a Satsails account is not held on Satsails' servers. It sits on three public networks at once: Bitcoin mainnet, the Liquid sidechain, and a Coinos-operated Lightning account. The wallet is built in Flutter over a Rust core, using BDK for Bitcoin and LWK for Liquid — its own README states this. That one architectural fact decides the whole job. Most of what an integrator wants is recoverable from public chain data given the account holder's descriptors; the part that is not — the DePix Pix on-ramp and the conversion orchestration — sits behind the app's backend and is reached by documenting that traffic. We do both, and hand back a single normalized read layer over the lot.

What a Satsails account holds

Each row below is a real surface of this wallet, not a generic list. The originating layer matters here, because it changes how durable the extraction is.

Data domainWhere it originatesGranularityWhat an integrator does with it
On-chain Bitcoin balance & historyBDK watch-only descriptor over Bitcoin mainnet (Esplora/electrs)Per-address UTXO, per-transactionPortfolio sync, accounting, reconciliation
Liquid balance & historyLWK descriptor over Liquid; confidential amounts unblinded with the blinding keyPer-asset, per-transaction (L-BTC, L-USDt, EURx, DePix)Multi-asset balance, stablecoin treasury views
Lightning balance & paymentsCoinos custodial account keyed to the app's account identifierInvoice / payment levelReceived and sent Lightning ledger
DePix on-ramp ordersSatsails backend plus the Pix payment partnerOrder: BRL amount, status, payer CPF/name metadataFiat-rail reconciliation, on-ramp tracking
Conversions and swapsBoltz (Lightning↔chain) and SideSwap (Liquid assets), routed by the appSwap id, pair, in/out amounts, feeConversion ledger, fee analysis
Payment pages / receive linksSatsails backendLink id, asset, requested amount, settlement txInvoicing, settlement matching
Account identitySatsails servers store a unique identifier and a public key (per the README)Identifier ↔ pubkey mappingTying backend records to on-chain activity

Three ways in, and the one we'd take

Watch-only chain derivation. Given the user's Bitcoin xpub and Liquid CT descriptor, full Bitcoin and Liquid balances and history reconstruct directly from public indexers, using the same BDK/LWK code path the app uses. Reachable: every on-chain asset the wallet shows. Effort is low to moderate; durability is very high because it is public chain data and does not break when the app's UI changes. We confirm the descriptor export path with the account holder during onboarding and stand up the indexer endpoint.

Backend protocol analysis. We capture and document the app-to-backend traffic: account registration (identifier plus pubkey), the DePix Pix on-ramp quote and order lifecycle, swap orchestration through Boltz and SideSwap, payment-page creation, and the Firebase push registration. This is the only place the fiat-rail and conversion context lives in a labelled form. Effort is moderate; durability is medium, so the delivery carries contract tests that flag a drifted endpoint before it reaches your data. We run this against a consenting account on an instrumented device, arranged with you.

Native export. The app surfaces transaction history; a periodic export gives a labelled ledger as a fallback when neither a descriptor nor traffic capture is wanted. Low effort, lower durability.

If we had to pick one, the descriptor-based chain read is the backbone — it is the canonical truth for a self-custody wallet and survives app releases — with the backend capture layered on for the Pix and swap context that chain data alone cannot label. That pairing is what we would build first.

Rebuilding a Liquid balance, in code

This is the core of route one: a watch-only Liquid wallet, amounts unblinded, DePix split out by asset id. The shapes are illustrative and get pinned against a consenting wallet during the build.

# Liquid (L-BTC / L-USDt / EURx / DePix) from a watch-only CT descriptor.
from lwk import Wollet, ElectrumClient, Network

DESC = "ct(slip77(<blinding_key>),elwpkh(<xpub>/<0;1>/*))"  # exported by the account holder
DEPIX_ASSET_ID = "<liquid_asset_id>"   # pinned during the build, never guessed

w = Wollet(Network.LIQUID, descriptor=DESC)
w.sync(ElectrumClient("ssl://blockstream.info:995"))

balances  = w.balance()                       # {asset_id: sats}, already unblinded
depix_brl = balances.get(DEPIX_ASSET_ID, 0) / 1e8
for tx in w.transactions():                   # full history, no Satsails server touched
    emit(tx.txid, tx.timestamp, tx.balance_changes)   # per-asset deltas

# DePix on-ramp order — backend surface, shape documented during protocol analysis.
# GET /v1/depix/orders/{order_id}    Authorization: Bearer <session>
# -> { "id", "amount_brl", "status": "pending|paid|settled",
#      "payer": { "cpf": "***", "name": "***" },        # minimized by default
#      "liquid_txid", "depix_amount" }
      

What lands in your repository

  • An OpenAPI specification for a normalized read API: balances per network, transaction history, DePix on-ramp orders, and the swap ledger.
  • A protocol and auth-flow report covering the identifier-plus-pubkey account registration, the Coinos Lightning session, the Firebase push registration, and the Pix partner handoff.
  • Runnable Python and Node.js source for the descriptor-based Bitcoin and Liquid balance/history, the DePix order poll, and the Boltz/SideSwap conversion ledger.
  • Automated tests against Bitcoin and Liquid testnet plus recorded backend fixtures, so a backend change shows up as a failing test.
  • Interface documentation and LGPD-aligned retention guidance, including default redaction of Pix payer metadata.

A normalized shape across the three chains

One account, one envelope, regardless of which layer a value came from:

{
  "account":  { "id": "<satsails_uid>", "pubkey": "<hex>", "custody": "self" },
  "balances": [
    { "network": "bitcoin",   "asset": "BTC",    "amount": "..." },
    { "network": "liquid",    "asset": "L-USDt", "amount": "..." },
    { "network": "liquid",    "asset": "DePix",  "amount": "...", "peg": "BRL 1:1" },
    { "network": "lightning", "asset": "BTC",    "amount": "...", "custodian": "Coinos" }
  ],
  "onramp_orders": [ { "rail": "Pix", "amount_brl": "...", "status": "...", "settled_tx": "..." } ],
  "swaps":         [ { "venue": "Boltz|SideSwap", "pair": "...", "in": "...", "out": "...", "fee": "..." } ]
}
      

The Brazilian rules that shape this

The personal data here is governed by the LGPD (Lei 13.709/2018), with the ANPD as authority. The lawful basis we work under is the account holder's explicit consent; the scope is limited to the asset classes asked for, and the CPF and payer name attached to a DePix on-ramp order are treated as sensitive — minimized and redacted by default unless the integration explicitly needs them. Consent is revocable: on revocation we drop the descriptor and delete any cached chain index, and consent records are logged. Brazil also has a virtual-asset framework — Lei 14.478/2022 (the Marco Legal dos Ativos Virtuais), reported by the Library of Congress as effective in 2023, and a set of Banco Central resolutions published in late 2025 that, per Notabene's analysis, are still phasing in. Those resolutions chiefly bind virtual-asset service providers; reading a consenting user's own self-custody wallet sits on the data-protection side, not VASP licensing, which keeps the compliance posture narrow and clear.

What this build has to get right

  • Liquid amounts are confidential. We unblind them with the descriptor's blinding key the account holder shares, and we keep the DePix / L-USDt / EURx / L-BTC asset-id split intact so a multi-asset balance is correct rather than collapsed into one figure.
  • Lightning is custodial through Coinos, so that slice cannot be derived from chain data. We capture the Coinos-side session during onboarding so the Lightning ledger is part of the unified view, not a silent gap.
  • The DePix on-ramp carries Pix payer identifiers. We design the pipeline to minimize and redact CPF and name at the boundary, persisting only what the integration is explicitly scoped to use.

Cost, and how a job runs

A Satsails integration is normally a one-to-two-week build, and you see the working code before any money changes hands. The first model is source-code delivery: runnable source, the OpenAPI spec, tests and interface docs land in your repository, and you pay from US$300 after delivery, once it runs against your own wallet and you are satisfied. The second is a hosted API: the same endpoints run by us, you call them and pay per call, with nothing up front. Access, the consenting test account and any compliance paperwork are arranged with you as part of the work. Tell us the wallet and what you need from its data — start at /contact.html.

What teams build on this

  • A Brazilian accounting tool reconciling a client's BTC and DePix holdings each month from a watch-only descriptor.
  • A treasury dashboard tracking L-USDt and DePix balances across several Satsails accounts in one view.
  • A tax export that follows the Pix → DePix → BTC on-ramp trail end to end for reporting.
  • A personal-finance app syncing a Satsails wallet alongside a user's bank data through one normalized API.

Screens we worked from

Satsails screenshot 1 Satsails screenshot 2 Satsails screenshot 3 Satsails screenshot 4 Satsails screenshot 5 Satsails screenshot 6 Satsails screenshot 7
Satsails screenshot 1 enlarged
Satsails screenshot 2 enlarged
Satsails screenshot 3 enlarged
Satsails screenshot 4 enlarged
Satsails screenshot 5 enlarged
Satsails screenshot 6 enlarged
Satsails screenshot 7 enlarged

Same category, named so the broader integration picture is clear — neutral, no ranking.

  • AQUA Wallet — non-custodial Bitcoin and USDt across mainnet, Lightning and Liquid; very close in shape to Satsails for a unified read.
  • Blockstream Green — Bitcoin on-chain plus native Liquid support; descriptor-based history maps the same way.
  • SideSwap — Liquid settlement and atomic asset swaps, listing USDt, EURx and DePix; relevant as the swap venue Satsails routes to.
  • Bull Bitcoin Mobile — Liquid for at-rest funds with Boltz swaps into Lightning; overlapping conversion surfaces.
  • Phoenix — non-custodial Lightning wallet; payment-level history that a combined ledger would normalize alongside.
  • Breez — non-custodial Lightning with its own node; comparable Lightning payment data.
  • Zeus — self-custody Lightning node control; channel and payment records relevant to the Lightning slice.
  • Wallet of Satoshi — custodial Lightning; a contrasting custody model an aggregator has to handle differently.

Questions integrators ask

Can balances be rebuilt without touching the Satsails servers?

For the on-chain part, yes. Given the account holder's Bitcoin xpub and Liquid CT descriptor, BTC, L-BTC, L-USDt, EURx and DePix balances and full history come straight from public indexers using the same BDK and LWK stack the app runs. Only the Pix on-ramp and the Coinos Lightning slice need the backend.

How is the DePix balance separated from L-USDt and L-BTC on Liquid?

On the Liquid Network every asset carries its own asset id and amounts are confidential. We unblind with the descriptor's blinding key and split by asset id, so DePix (described as a 1:1 BRL stablecoin) reports distinctly from L-USDt and L-BTC rather than collapsing into one number.

Does the Lightning history come through, given it is custodial?

Satsails Lightning is custodial and operated by Coinos per the wallet's own README, so it is not derivable from chain data. We capture that account's flow during onboarding so the Lightning ledger is included rather than missing from the unified view.

Which Brazilian rules apply to reading a consenting user's Satsails wallet?

LGPD governs the personal data — account-holder consent, data minimization, and ANPD oversight. The Banco Central virtual-asset resolutions published in late 2025 are still phasing in and chiefly bind service providers, not a consented read of a user's own self-custody wallet.

Sources, and who put this together

This mapping was built from the wallet's own public repository (libraries, custody model, the identifier-and-pubkey backend note), Brazilian crypto coverage of its DePix and fee design, the Banco Central virtual-asset analysis, and the Google Play listing for the package identifier. Checked in May 2026 against those primary sources: Satsails README, Notabene on the BCB resolutions, Livecoins coverage, Google Play listing.

Mapped by the OpenBanking Studio integration desk, May 2026.

Satsails — factual recap

Satsails is a self-custody wallet from Brazil combining Bitcoin, the Liquid sidechain, Lightning and stablecoins (L-USDt, EURx, and DePix, described in Brazilian coverage as a 1:1 BRL stablecoin on Liquid). Bitcoin and Liquid are non-custodial; Lightning is custodial and operated by Coinos, per the project's README. The app is built in Flutter over a Rust core using BDK and LWK, with conversions routed through Boltz and SideSwap, and a Pix on-ramp for buying DePix with Brazilian Reais. Distributed on Google Play under the package identifier com.satsails.Satsails (per its Play listing) and on the App Store; the source repository is public at github.com/Satsails. Brazilian press reports a conversion fee around 2% (1.5% with an affiliate code); figures here are attributed to those sources, not asserted independently. Satsails is an independent product named here only to describe interoperability work.

Mapping reviewed 2026-05-17