Summary
When connected to OpenSea via KeepKey Vault and attempting to purchase a Solana NFT, the transaction fails with:
Transaction failed: Vault sign failed (500): {"error":"Malformed Solana transaction","code":3}
Steps to Reproduce
- Connect KeepKey Vault to OpenSea via WalletConnect
- Find a Solana NFT and initiate a purchase
- Approve the transaction prompt
- Error:
Vault sign failed (500): {"error":"Malformed Solana transaction","code":3}
Root Cause
The /solana/sign-transaction handler in Vault strips the signature prefix from the raw transaction before sending to the device using a hand-rolled compact-array parser:
let pos = 0, sigCount = 0;
if (fullTx[0] < 128) {
sigCount = fullTx[0];
pos = 1;
} else if (fullTx.length >= 2 && fullTx[1] < 128) {
sigCount = fullTx[0] & 127 | fullTx[1] << 7;
pos = 2;
} else if (fullTx.length >= 3) {
sigCount = fullTx[0] & 127 | (fullTx[1] & 127) << 7 | fullTx[2] << 14;
pos = 3;
}
const messageStart = pos + sigCount * 64;
deviceRawTx = Buffer.from(fullTx.subarray(messageStart)).toString("base64");
OpenSea sends versioned transactions (Solana v0 with address lookup tables), which have a 0x80 version prefix byte before the compact-array signature count. This causes the parser to misidentify the transaction boundaries, producing a malformed message payload that the firmware rejects with code: 3.
Expected Behavior
Vault should correctly parse both legacy and versioned (v0) Solana transactions before passing them to the device.
The fix should detect the version prefix byte (0x80 for v0 transactions) and adjust parsing accordingly:
let versionedOffset = 0;
if (fullTx[0] === 0x80) {
versionedOffset = 1; // skip version prefix
}
// then parse compact-array from fullTx[versionedOffset]
Environment
- Vault version: 1.2.16
- Firmware: 7.14.0
- Experimental policy: enabled
- OS: macOS
- dApp: OpenSea (Solana NFT purchase)
Related
Summary
When connected to OpenSea via KeepKey Vault and attempting to purchase a Solana NFT, the transaction fails with:
Steps to Reproduce
Vault sign failed (500): {"error":"Malformed Solana transaction","code":3}Root Cause
The
/solana/sign-transactionhandler in Vault strips the signature prefix from the raw transaction before sending to the device using a hand-rolled compact-array parser:OpenSea sends versioned transactions (Solana v0 with address lookup tables), which have a
0x80version prefix byte before the compact-array signature count. This causes the parser to misidentify the transaction boundaries, producing a malformed message payload that the firmware rejects withcode: 3.Expected Behavior
Vault should correctly parse both legacy and versioned (v0) Solana transactions before passing them to the device.
The fix should detect the version prefix byte (
0x80for v0 transactions) and adjust parsing accordingly:Environment
Related