Skip to content

fix(km): make Albedo and Freighter signing follow the configured network - #259

Merged
CassioMG merged 2 commits into
mainfrom
fix/km-albedo-freighter-network
Oct 15, 2026
Merged

CassioMG merged 2 commits into
mainfrom
fix/km-albedo-freighter-network

Conversation

@CassioMG

@CassioMG CassioMG commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR

Closes https://github.com/stellar/wallet-eng-monorepo/issues/95

Correctness fixes for signing with keys held by Albedo or Freighter. The Albedo handler now picks the network the same way the Freighter handler does, both handlers check that the network they sign for matches the transaction's, and keys without a network use the key manager's default network when signing and when fetching SEP-10 auth tokens.

Version bumps and changelog entries will come with the next release PR.

Implementation details (for agents)

What changed

  • The Albedo handler resolves the network like the Freighter handler (custom.networkPassphrase, then key.network, then Networks.PUBLIC), maps it to Albedo's network name (public or testnet), passes it to albedo.tx(), and parses the signed envelope with it. Previously it relied on Albedo's default network and parsed with a fixed Networks.PUBLIC. Networks Albedo's tx intent doesn't support are rejected before Albedo opens, and a response for another network is rejected.
  • The Albedo and Freighter handlers throw a Network mismatch error, before opening the wallet, when the resolved network differs from transaction.networkPassphrase.
  • KeyManager.signTransaction() sets custom.networkPassphrase from key.network, then defaultNetworkPassphrase, when the caller doesn't, and passes the caller's other custom fields through. The handlers can't see the manager's default otherwise.
  • KeyManager.fetchAuthToken() passes the network the challenge was validated against (key.network, then defaultNetworkPassphrase) to the handler.
  • The doc comments for BaseKey.network, the custom param of signTransaction() and setDefaultNetworkPassphrase() describe the fallback.

Behavior changes

  • Albedo keys follow the configured network, as Freighter keys do.
  • Albedo and Freighter keys throw instead of signing when the transaction is for a different network than the one resolved from custom.networkPassphrase, key.network or the default.
  • Albedo and Freighter keys without a network use the key manager's default network. Signing a transaction for another network with them needs key.network or custom.networkPassphrase.
  • Plaintext and Ledger keys are unaffected. They already sign for the transaction's own network.

Tests

  • New albedo.test.ts, with a stand-in for Albedo in test/fixtures/albedo.ts that signs for the requested network as albedo.link does. It covers signing for the key's network, custom.networkPassphrase taking precedence, the default network, a response for the wrong network, networks Albedo doesn't support, network mismatches, a key that holds a private key, and a missing signed envelope.
  • freighter.test.ts covers network mismatches.
  • keyManager.test.ts covers the default network in signTransaction() and fetchAuthToken(), including a transaction for another network refused by the key manager and the caller's other custom fields reaching Freighter.
  • yarn build and yarn test:ci: 364 passing. ESLint, Prettier and tsc --noEmit are clean for the changed files.

🤖 Generated with Claude Code

Correctness fixes for how the key manager picks the network when a key
is held by an external wallet (Albedo or Freighter).

- Albedo handler: resolve the network the same way the Freighter
  handler does (custom.networkPassphrase, then key.network, then
  Networks.PUBLIC), pass it to Albedo, and parse the signed envelope
  with it, instead of relying on Albedo's default network and a fixed
  Networks.PUBLIC. Networks Albedo's tx intent doesn't support are
  rejected before Albedo opens, and a response for another network is
  rejected.
- Albedo and Freighter handlers: throw a "Network mismatch" error,
  before opening the wallet, when the resolved network differs from the
  transaction's networkPassphrase.
- KeyManager.signTransaction(): for keys without a network, fall back
  to defaultNetworkPassphrase. The caller's custom.networkPassphrase and
  the key's network still come first, and other custom fields are passed
  through unchanged.
- KeyManager.fetchAuthToken(): pass the network the challenge was
  validated against to the handler, so Albedo and Freighter keys without
  a network sign the challenge for that network.

Tests:
- Add albedo.test.ts, with a stand-in for Albedo that signs for the
  requested network as albedo.link does. It covers signing for the
  key's network, custom.networkPassphrase taking precedence, the
  default network, a response for the wrong network, networks Albedo
  doesn't support, and network mismatches.
- Cover network mismatches in freighter.test.ts.
- Cover the defaultNetworkPassphrase fallback in signTransaction() and
  fetchAuthToken() in keyManager.test.ts, including a transaction for
  another network refused by a KeyManager and the caller's other custom
  fields reaching Freighter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 15, 2026 20:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The changes span multiple signing integrations and network-validation paths, warranting final human review.

0 open findings

What changed in this PR

Fixes Albedo and Freighter signing to honor configured networks and prevent cross-network signing.

Changes:

  • Adds network resolution and validation for Albedo and Freighter.
  • Propagates default networks through signing and SEP-10 authentication.
  • Adds comprehensive network-related tests and fixtures.
File Description
@stellar/​typescript-wallet-sdk-km/​test/​keyManager.test.ts Tests manager defaults and external-wallet integration.
@stellar/​typescript-wallet-sdk-km/​test/​freighter.test.ts Tests Freighter network mismatches.
@stellar/​typescript-wallet-sdk-km/​test/​fixtures/​albedo.ts Provides an Albedo signing fixture.
@stellar/​typescript-wallet-sdk-km/​test/​albedo.test.ts Tests Albedo network behavior.
@stellar/​typescript-wallet-sdk-km/​src/​Types/​index.ts Documents default network behavior.
@stellar/​typescript-wallet-sdk-km/​src/​keyManager.ts Applies network fallbacks and propagates custom options.
@stellar/​typescript-wallet-sdk-km/​src/​Handlers/​freighter.ts Rejects network-mismatched transactions.
@stellar/​typescript-wallet-sdk-km/​src/​Handlers/​albedo.ts Resolves and validates Albedo networks.

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@CassioMG

Copy link
Copy Markdown
Contributor Author

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

@CassioMG
CassioMG requested a review from a team October 15, 2026 20:57
@CassioMG CassioMG self-assigned this Oct 15, 2026
Albedo builds the network field of its tx response from the request's
own network param, so now that the handler always sends the network,
the check could never fail. The network is already pinned by sending
it, by the network mismatch check, and by parsing the signed envelope
with the same passphrase.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 15, 2026 22:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Albedo must reject signed responses whose returned network does not match the requested network.

1 open finding

🧠 Review effort: Lite

@CassioMG
CassioMG merged commit 5c69496 into main Oct 15, 2026
8 of 9 checks passed
@CassioMG
CassioMG deleted the fix/km-albedo-freighter-network branch October 15, 2026 23:28
@CassioMG CassioMG mentioned this pull request Oct 15, 2026
CassioMG added a commit that referenced this pull request Oct 19, 2026
* Release/5.1.0

Bumps all three packages to `5.1.0` and updates their changelogs.

* fix(recovery): validate SEP-30 signer set before locking the master key (#255)
* fix(km): make changePassword work with BrowserStorageKeyStore (#257)
* chore(deps): bump pbkdf2, sha.js and cipher-base in yarn.lock (#258)
* fix(km): make Albedo and Freighter signing follow the configured network (#259)

A minor release rather than a patch: #255 adds four exported error
classes, and #255 and #259 make calls that used to succeed throw.

`@stellar/typescript-wallet-sdk-soroban` has no shipped changes since 5.0.0
and is bumped to stay in lockstep, matching #250.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: raise testnet test timeouts to 30s

Unit tests that fund accounts through friendbot or authenticate against
testanchor kept timing out in CI: friendbot fundings were taking 4-30s,
against hook and test limits of 5-20s and Jest's 5s default. The
timeouts fail `yarn test:ci` in the npm publish workflows before the
publish step runs.

- Set `testTimeout: 30000` at the top level of jest.config.js. It's a
  global option, so it can't go in the per-project config.
- Raise every explicit test and hook timeout under 30s to 30s. Those
  already at 30s or more are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants