Skip to content
Draft
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
5 changes: 5 additions & 0 deletions packages/snap/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Validate that account IDs passed to `keyring_setSelectedAccounts` belong to the snap, rejecting unknown IDs with `InvalidParamsError` ([#604](https://github.com/MetaMask/snap-solana-wallet/pull/604))

### Fixed

- **BREAKING:** `signTransaction` and `signAllTransactions` now preserve the original `messageBytes` of a compiled `VersionedTransaction` verbatim and only append the account's signature (#[0000](https://github.com/MetaMask/snap-solana-wallet/pull/0000))
- Previously, an unsigned compiled transaction was silently decompiled and recompiled, which canonicalised the account order and remapped instruction account indices — breaking multi-party signing flows.

## [2.8.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snap-solana-wallet.git"
},
"source": {
"shasum": "AzXzPnYm37l2ijVy4ZM6GRu3DouI8hs75QHbfXJ/sBQ=",
"shasum": "2hll3bYQPDYuEYTjkPO0FSfFD9j7c/++LaL9SHU1BrI=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
31 changes: 8 additions & 23 deletions packages/snap/src/core/services/signer/Signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,29 +95,14 @@ export class Signer {
);
}

const isUnsigned = Object.values(
transactionMessageOrTransaction.signatures,
).every((signature) => !signature);

// It's an unsigned transaction, grab the message from the transaction and apply the same logic as above.
if (isUnsigned) {
const { messageBytes } = transactionMessageOrTransaction;

const transactionMessageFromUnsignedTransaction =
await fromBytesToCompilableTransactionMessage(
messageBytes,
rpc,
config,
);

return this.#prepareAndPartiallySignTransactionMessage(
transactionMessageFromUnsignedTransaction,
account,
network,
);
}

// It's a partially signed transaction, so we cannot alter its content, and we add the account's signature.
// It's a compiled transaction (either unsigned or partially signed).
// Per the Wallet Standard `signTransaction` contract, we MUST NOT mutate
// the message bytes — only append the account's signature. Decompiling and
// recompiling here would canonicalise the account ordering and remap
// instruction account indices, breaking multi-party signing flows where
// a counterparty has already signed the original bytes
//
// See: https://consensyssoftware.atlassian.net/browse/WPN-1035
return this.#partiallySignTransaction(
transactionMessageOrTransaction,
account,
Expand Down
Loading