refactor: sign with the official transaction client - #122
Merged
Conversation
`partisia-blockchain-applications-crypto` was last published 2024-10-04 and is no longer maintained. It carried 11 advisories, 5 of them critical, pinned `bip32` and `bip39` to exact versions that cannot be patched, and pulled in zxcvbn -- a 3.4 MB password-strength dictionary -- for a blockchain SDK. The official replacement, `@partisiablockchain/blockchain-api-transaction-client`, was already installed as a dependency of `@partisiablockchain/abi-client`. It is now a direct dependency and does the signing. `SignedTransaction.create` serializes, hashes and signs in one call, so the four `createTransactionFrom*` functions -- each repeating serialize, digest, sign, concatenate, base64, broadcast -- collapse into a single `createTransaction` plus four small `SenderAuthentication` implementations in `transactions/authentication.ts`: privateKey SenderAuthenticationKeyPair.fromString (provided) Ledger wraps the existing PartisiaLedgerClient MetaMask wraps the existing snap wallet_invokeSnap call partisiaSdk wraps PartisiaSdk.signMessage `serializeTransaction` in `transactions/helper.ts` is gone; the module keeps `builderToBytesBe`, `getChainId` and the result poller. The bytes are identical. Verified against the old package for a fixed key, nonce, gas and payload: same account address, same serialized transaction (nonce, valid-to and gas as big-endian i64s, then the contract address and the length-prefixed payload) and same signing digest (SHA-256 over those bytes plus the length-prefixed chain id). One deliberate difference: the old package signed with elliptic's `canonical: true`, the official client uses the default, so the low-s and high-s forms of the same signature are produced. Both are valid ECDSA over the same digest and recover the same public key -- the 65-byte encoding carries the recovery parameter -- and the full testnet suite confirms the chain accepts them. Two behavioural notes: - The Partisia wallet now signs with `dontBroadcast: true` and the SDK broadcasts, so every strategy goes to the chain the same way and its result is polled the same way. - Broadcast retries on a spent nonce are limited to non-interactive signers. Retrying a Ledger or wallet signature would silently prompt the user again. Bundled with esbuild (--bundle --minify --format=esm --splitting), total bytes across all chunks 915,298 -> 543,045 (-372,253, -40.7%); the entry chunk 345,347 -> 247,853 (-28.2%). The 343 KB wallet-crypto chunk is gone. `partisia-blockchain-applications-sdk` stays: it is the browser wallet connector and has no official replacement. It is used as a type only -- the connected client is passed in by the consumer -- so the SDK never imports it or its crypto subtree at runtime. 21 suites / 269 tests pass against live testnet.
|
Total Coverage: 91.88% Coverage Report
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
Step 2 and 3 of
PLAN-drop-unmaintained-partisia-deps.md. #120 did step 1.Why
partisia-blockchain-applications-cryptowas last published 2024-10-04 and is unmaintained. It carries 11 advisories, 5 critical, pinsbip32@=2.0.6andbip39@=3.1.0with=so no patched version can float in, and pulls zxcvbn (3.4 MB installed) — a password-strength dictionary — into a blockchain SDK.The official replacement,
@partisiablockchain/blockchain-api-transaction-client, was already installed as a dependency of@partisiablockchain/abi-client. This makes it a direct dependency and hands it the signing.What
SignedTransaction.createserializes, hashes and signs in one call. The fourcreateTransactionFrom*functions — each repeating serialize → digest → sign → concatenate → base64 → broadcast — collapse into onecreateTransactionplus four smallSenderAuthenticationimplementations in the newtransactions/authentication.ts:privateKeySenderAuthenticationKeyPair.fromString— provided by the official clientLedgerPartisiaLedgerClientMetaMaskwallet_invokeSnapcallpartisiaSdkPartisiaSdk.signMessageserializeTransactionis deleted fromtransactions/helper.ts, which keepsbuilderToBytesBe,getChainIdand the result poller.src/transactions/index.tsgoes from 198 lines of four near-identical pipelines to one function.The public API does not move:
setSigningStrategyis unchanged, andContractRepository.createTransactionpicks the backend behind the same dynamic import as before.The bytes are identical — verified, not assumed
Checked against the old package for a fixed key, nonce, gas, payload and chain id:
The one difference: the old package signed with elliptic's
canonical: true, the official client uses the default. That produces the low-s and high-s forms of the same signature — samer, ands_old + s_new == n. Both are valid ECDSA over the same digest and recover the same public key, since the 65-byte encoding carries the recovery parameter. The full testnet suite (≈40 real transactions: registrations, transfers, renewals, record mints and updates) passes, so the chain accepts them.Behaviour changes, deliberate
dontBroadcast: trueand the SDK broadcasts through the reader node, so every strategy reaches the chain the same way and its result is polled the same way.Measured
esbuild
--bundle --minify --format=esm --splitting --platform=node, againstmain(with #120 in):mainmainThe 343,654-byte wallet-crypto chunk — bip39's wordlists for every supported language — is gone entirely.
Production advisory count does not change (3 low, all
elliptic, already the state after #115'sresolutions). The dependency graph stays at 107 packages too, becausepartisia-blockchain-applications-sdkstill depends on the crypto package. What changes is structural: no SDK code path imports the abandoned package any more, so nothing it pins can break a build or ship in a bundle.What stays
partisia-blockchain-applications-sdk— the browser wallet connector, no official replacement (@partisiablockchain/snapcovers the MetaMask path the SDK already calls directly). It is used as a type only: the connected client is passed in by the consumer, so the SDK never imports it or its crypto subtree at runtime.Note for the app-side migration
PLAN-drop-unmaintained-partisia-deps.mdsuggests importingCryptoUtilsfrom the package root. It is not exported there —@partisiablockchain/blockchain-api-transaction-clientre-exports the OpenAPI runtime,BlockchainTransactionClient,SignedTransaction,SenderAuthenticationKeyPairand the types, butCryptoUtilshas to come from@partisiablockchain/blockchain-api-transaction-client/target/main/CryptoUtils. ItskeyPairToAccountAddress(privateKeyToKeypair(pk))does produce the same address as the oldprivateKeyToAccountAddress— verified above.Test status
npx tsc --noEmitclean,eslintclean,yarn buildclean,npx jest -i— 21 suites / 269 tests pass against the live testnet.https://claude.ai/code/session_01GceWCwGXu66D1xEBDxZWBb