fix: align shell-sdk signing hashes with shell-chain v0.23.0#21
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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 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 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 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 on lines
+437
to
+439
| new Uint8Array([signatureTypeToId(signatureType)]), | ||
| new Uint8Array([txType]), | ||
| ]; |
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; | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
keccak256(RLP(tx))helpers with the canonical shell-chain v0.23.0 BLAKE3 signing preimages0.9.2Validation
npm run buildnpm testImpact-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.