Skip to content

fix: align shell-sdk signing hashes with shell-chain v0.23.0#21

Merged
LucienSong merged 1 commit into
mainfrom
security/sdk-signing-hash-blake3
May 25, 2026
Merged

fix: align shell-sdk signing hashes with shell-chain v0.23.0#21
LucienSong merged 1 commit into
mainfrom
security/sdk-signing-hash-blake3

Conversation

@LucienSong
Copy link
Copy Markdown
Collaborator

Summary

  • replace legacy keccak256(RLP(tx)) helpers with the canonical shell-chain v0.23.0 BLAKE3 signing preimages
  • fix AA sender/paymaster hashing, add Rust-compatible vectors, and guard AA signing so bundle hashes cannot silently fall back to the legacy path
  • add signer disposal helpers and zero decrypted secret-key buffers after keystore decryption
  • bump the SDK package version to 0.9.2

Validation

  • npm run build
  • npm test

Impact-Deferred: shell-dex: downstream UI build/smoke tests require the separate DEX repo and were not run in this SDK PR.
Impact-Deferred: shell-explorer: explorer smoke tests require the separate repo and a live devnet.
Impact-Deferred: shella-chrome-wallet: wallet integration/keystore round-trip tests require the separate repo and extension environment.
Impact-Deferred: shell-site: site docs/examples live in the separate site repo and were not updated in this SDK-only PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 17:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates shell-sdk’s signing and hashing logic to match shell-chain v0.23.0, switching from legacy keccak256(RLP(tx)) hashing to canonical BLAKE3 structured-preimage hashes (including AA bundle/paymaster flows), while also improving key material lifecycle handling (dispose/zeroization) and bumping the package version to 0.9.2.

Changes:

  • Replace legacy transaction + AA sender hashing with shell-chain v0.23.0 BLAKE3 signing preimages; add paymaster signing hash helper and updated deterministic vectors.
  • Add signer/adapter disposal and keystore decryption zeroization helpers; add withDecryptedKeystoreSigner() convenience API.
  • Update integration/unit tests, fixtures, docs (README/CHANGELOG), and bump package versions.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/node.integration.test.mjs Updates integration tests to rely on auto-derived hashes, adds disposal and AA-guard coverage.
tests/fixtures/rust-compatibility.json Regenerates Rust-compat transaction hash vectors for the new signing hash scheme.
tests/browser.integration.test.mjs Removes manual hashTransaction usage in browser integration flow.
tests/aa.test.mjs Updates AA hash assertions for BLAKE3, adds fixed vectors and paymaster hash coverage.
src/transactions.ts Implements BLAKE3 structured-preimage hashing for txs + AA sender/paymaster hashes; introduces encoding helpers.
src/signer.ts Adds dispose() support, guards AA signing, and auto-computes correct signing hashes when txHash is omitted.
src/keystore.ts Zeroes decrypted key material, documents disposal, and adds withDecryptedKeystoreSigner() helper.
src/index.ts Re-exports new helpers (hashPaymasterTransaction, withDecryptedKeystoreSigner).
src/adapters.ts Adds adapter secret-key lifecycle management (cloning + disposal/zeroization) and safer public key accessors.
README.md Updates v0.23.0 alignment notes and examples to reflect the new hashing/signing behavior.
package.json Bumps SDK version to 0.9.2.
package-lock.json Updates lockfile package version to 0.9.2.
CHANGELOG.md Adds 0.9.2 release notes reflecting hashing, AA, and disposal changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/signer.ts
Comment on lines +189 to +191
if (options.tx.tx_type === 0x7e && !options.aaBundle) {
throw new Error("aaBundle is required when signing AA bundle transactions");
}
Comment thread src/transactions.ts
Comment on lines +598 to 602
* The signing-form bundle omits `paymaster_signature`, `session_auth.root_signature`,
* and `session_auth.session_signature`, but still commits to `paymaster_context`.
*
* @param tx - The outer unsigned transaction (must have `tx_type = 0x7E`).
* @param bundle - The AA bundle that will be attached.
Comment thread src/transactions.ts
Comment on lines +27 to +36

const BATCH_SIGNING_HASH_DOMAIN = AA_BUNDLE_TX_TYPE;
const PAYMASTER_SIGNING_HASH_DOMAIN = 0x7f;

const SIGNATURE_TYPE_IDS: Record<SignatureTypeName, number> = {
"ML-DSA-65": 1,
Dilithium3: 0,
MlDsa65: 1,
SphincsSha2256f: 2,
};
Comment thread src/transactions.ts
Comment on lines +437 to +439
new Uint8Array([signatureTypeToId(signatureType)]),
new Uint8Array([txType]),
];
Comment thread src/transactions.ts
Comment on lines 627 to 631
bundle.paymaster_context && bundle.paymaster_context.length > 0
? (bytesToHex(new Uint8Array(bundle.paymaster_context)) as HexString)
: ("0x" as HexString);

const txFields = [
toRlpUint(tx.chain_id),
toRlpUint(tx.nonce),
tx.to ? bytesToHex(shellAddressToBytes(tx.to)) : "0x",
toRlpUint(tx.value),
tx.data,
toRlpUint(tx.gas_limit),
toRlpUint(tx.max_fee_per_gas),
toRlpUint(tx.max_priority_fee_per_gas),
toRlpAccessList(tx.access_list),
toRlpUint(tx.tx_type ?? AA_BUNDLE_TX_TYPE),
toRlpUint(tx.max_fee_per_blob_gas != null ? 1 : 0),
toRlpUint(tx.max_fee_per_blob_gas ?? 0),
(tx.blob_versioned_hashes ?? []).map((hash) => hash as HexString),
] as const;

const bundleSigningFields = [innerCallsRlp, paymasterField, paymasterContextField] as const;

@LucienSong LucienSong merged commit 7449aa6 into main May 25, 2026
2 checks passed
@LucienSong LucienSong deleted the security/sdk-signing-hash-blake3 branch May 25, 2026 17:32
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.

2 participants