Skip to content

fix: pin signer address and verify it on lockAssets/unlockAssets/setBoost - #178

Merged
prodbycorne merged 5 commits into
SmartDropLabs:mainfrom
abayomicornelius:fix/pin-signer-address
Aug 16, 2026
Merged

fix: pin signer address and verify it on lockAssets/unlockAssets/setBoost#178
prodbycorne merged 5 commits into
SmartDropLabs:mainfrom
abayomicornelius:fix/pin-signer-address

Conversation

@abayomicornelius

Copy link
Copy Markdown
Contributor

Summary

  • lockAssets, unlockAssets, and setBoost called Freighter's signTransaction without pinning address, so any connected account could sign, and the returned signerAddress was never checked against the account SmartDrop believes is connected.
  • A signer mismatch previously surfaced only as an opaque on-chain authorization failure after a real transaction had already been submitted, instead of failing fast client-side.
  • Now address: userAddress is passed in the signing request (so Freighter itself can refuse a mismatched account), and getSignedTransactionXdr throws a SecurityError if result.signerAddress disagrees with the expected account — before sendTransaction is ever reached. Legacy bare-string signTransaction responses (no signerAddress field) are unaffected.

Closes #139

Test plan

  • npx vitest run src/lib/soroban.service.test.ts — new signer-pinning tests pass (mismatch rejects with SecurityError and never calls sendTransaction; matching signer proceeds; address is passed through; legacy bare-string response still works)
  • npx vitest run (full suite) — no new failures (one pre-existing, unrelated formatCredits rounding failure confirmed present on a clean upstream/main baseline)
  • npx tsc --noEmit — clean
  • npm run lint — clean (only pre-existing unused-var warnings, unrelated to this change)
  • npm run build — succeeds
  • CI e2e (Playwright) — could not run locally (Playwright's chromium build isn't supported on this machine's macOS version); will verify on the PR's GitHub Actions run

@netlify

netlify Bot commented Aug 16, 2026

Copy link
Copy Markdown

Deploy Preview for spiffy-melomakarona-eb1e8a ready!

Name Link
🔨 Latest commit 902f7f3
🔍 Latest deploy log https://app.netlify.com/projects/spiffy-melomakarona-eb1e8a/deploys/6a824d4c3139780008a1344b
😎 Deploy Preview https://deploy-preview-178--spiffy-melomakarona-eb1e8a.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Aug 16, 2026

Copy link
Copy Markdown

Deploy Preview for smart-drop ready!

Name Link
🔨 Latest commit 902f7f3
🔍 Latest deploy log https://app.netlify.com/projects/smart-drop/deploys/6a824d4cb5a69b0008a8de4d
😎 Deploy Preview https://deploy-preview-178--smart-drop.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

…address

Freighter's signTransaction accepts an optional address field to pin
which account is required to sign. Widening the type here so call
sites can start passing it.
…actionXdr

Adds an expectedSigner parameter and throws a SecurityError when
Freighter's response reports a signerAddress that disagrees with it,
before the caller ever gets a signed XDR back to submit. Responses
that omit signerAddress (older Freighter versions, or the legacy
bare-string shape) are unaffected since there's nothing to check
against.
…t signing calls

Passes address: userAddress in the signTransaction request (letting
Freighter itself refuse a mismatched account) and the expected signer
into getSignedTransactionXdr's new check, for all three flows that
sign and submit a transaction on the user's behalf.

Closes SmartDropLabs#139
signTransaction's options now include address, so the existing exact
call-shape assertion needs to expect it too. Also imports SecurityError
ahead of the new signer-pinning tests.
Adds cases for each of the three signing flows: a mismatched
signerAddress rejects with SecurityError and never reaches
sendTransaction, a matching signerAddress proceeds normally, and the
legacy bare-string signTransaction response (no signerAddress field)
is still accepted unchanged.
@prodbycorne

Copy link
Copy Markdown
Contributor

All ci s passed

@prodbycorne
prodbycorne merged commit ba92037 into SmartDropLabs:main Aug 16, 2026
9 checks passed
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.

lockAssets/unlockAssets/setBoost never pin address in Freighter's signTransaction call and never validate the returned signerAddress

2 participants