Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Ephemeral Account in the Product Narrative

`docs/GLOSSARY.md` defines the pieces individually. This entry strings them
together into the story a user actually lives through.

## Starting definitions

Paraphrasing the existing glossary:

- **Bridgelet** — an open-source infrastructure layer for sending blockchain
payments to people who don't have wallets yet, by creating ephemeral accounts
that can later be claimed and swept.
- **Ephemeral Account** — a temporary Stellar account created for a recipient who
does not yet have a wallet.
- **Claim Token / Claim URL** — the token, and the link carrying it, that let a
recipient claim the funds.
- **Expiration** — the point after which an unclaimed account or token is invalid.

The ephemeral account is the hinge the whole product turns on: it is what lets a
sender send *before* the recipient has anywhere to receive.

## The narrative arc

1. **Sender creates a payment intent.** Alice connects a wallet on `/send` and
says how much to send — critically, without needing Bob's wallet address.
2. **An ephemeral account is created.** Bridgelet provisions a temporary Stellar
account and funds it. Nobody has claimed it; it is a parking place with a
deadline.
3. **Recipient receives a claim link.** Bob gets a `/claim/[token]` URL through
whatever channel Alice uses — chat, email, SMS.
4. **Recipient claims.** Bob opens the link. He does not need a pre-existing
wallet; if he has none, a keypair can be generated for him.
5. **Funds sweep.** The ephemeral account's balance moves to Bob's destination
wallet, and the temporary account has served its purpose.

If step 4 never happens, **Expiration** governs what becomes of the funds.

## Where the technical detail lives

This is deliberately the *product* view. The on-chain mechanics — how the
ephemeral account is created and funded, what the sweep transaction looks like,
and the already-swept guard preventing a double claim — are documented in the
`bridgelet-audit/` initiative's `ephemeral-account.md` entry for `bridgelet-core`.
Read that for what actually happens on-ledger.
46 changes: 46 additions & 0 deletions bridgelet-product-audit/glossary/org-integration-api-key-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Org Integration API Key Model (Option A)

## The deferral

`docs/sender-auth-model.md` evaluates three sender-auth options and picks Option B
(wallet-based). Option A — a static API key supplied via an `X-API-Key` header
from the environment — is **rejected for the browser UI**, on the grounds that any
key shipped to a browser would leak in the JS bundle.

But the same document does not discard Option A entirely. Its Security Notes
state that for server-side and org integrations calling the Bridgelet API from a
backend, an env-level API key remains viable, and that **this flow "should be
documented separately in an integration guide."**

This entry exists to track whether that separate documentation now exists.

## Does the integration guide cover it?

`docs/integration-guide.mdx` (with a paired `integration-guide.pdf`) does exist,
and it **does** reference an API key — it shows SDK construction as
`new BridgeletSDK({ apiKey: process.env.BRIDGELET_API_KEY })` and lists
`BRIDGELET_API_KEY` in its environment-variable table.

So the *mechanical* usage is documented: an integrator knows the variable name
and how to pass it to the SDK.

## The gap, stated plainly

What the integration guide does **not** appear to cover is the *auth model*
itself, which is what `sender-auth-model.md` deferred. Specifically, nothing found
during this review documents:

- How an org **obtains** an API key, or who issues it.
- Key **rotation** or revocation.
- What **scope or authority** a key carries — can it create payment intents on
behalf of arbitrary senders?
- How the key-based path relates to the wallet-signature proof that Option B
relies on, given the two establish authority very differently.

This is recorded as a gap, not filled in here. Answering these speculatively
would risk documenting an auth model that was never designed. The open question
belongs back with `sender-auth-model.md`'s authors.

## Related

- [`sender-vs-recipient-auth-models.md`](./sender-vs-recipient-auth-models.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Sender vs Recipient Auth Models

Bridgelet runs **two distinct authentication models** at once. They are easy to
conflate because both are described loosely as "connecting a wallet", but they
answer different questions and use different credentials.

## Sender side — wallet-based

The canonical record is `docs/sender-auth-model.md`, which selects **Option B,
wallet-based auth via Freighter** for the `/send` page.

Key properties of that decision:

- The sender's Stellar **public key is the identity**.
- **No JWT and no session token** is issued or stored. Per that document, "wallet
ownership is proven at transaction-signing time" — the signature *is* the proof.
- Option A (a static `X-API-Key`) was rejected for the browser UI specifically
because the key would leak in the JS bundle. It remains viable for backend
integrations — see
[`org-integration-api-key-model.md`](./org-integration-api-key-model.md).

## Recipient side — claim-token-based

The recipient side works on a completely different credential. A recipient does
not authenticate as an identity at all; they present a **claim token**, delivered
as a URL (`/claim/[token]`). Possession of the link is the credential.

This is a **bearer** model: it answers "does this person hold a valid claim
token?" rather than "who is this person?". Nothing about it proves wallet
ownership, and no signature is involved in reaching the claim page.

## Where the two intersect

The separation is not absolute. A claim token gets the recipient *to* the funds,
but sweeping those funds into a permanent account eventually requires a
destination wallet — at which point the recipient acquires a wallet too (possibly
via the `generated` path, if they have none).

So the models meet at the moment of sweep: **token-as-credential** for access,
**wallet-as-destination** for settlement. Whether the current claim UI actually
requires a connected wallet is traced in
[`claim-flow-wallet-requirement.md`](../integration-notes/claim-flow-wallet-requirement.md).
Loading