@solana/kit
v8.5.0 (2026-10-13)
Minor Changes
-
[
@solana/addresses] #2115e59ed8bThanks @lorisleiva! - AllowgetAddressEncoder()andgetAddressCodec()to encode any address-bearing object (HasAddress) in addition to plainAddressvalues, so that signers and framework wrapper classes can be encoded directly without unwrapping them first. Decoders still return a plainAddress. As a result, the encoder input type of codecs composing an address codec (e.g. a struct with an address field) is now inferred asAddress | HasAddressinstead ofAddress.const addressEncoder = getAddressEncoder(); addressEncoder.encode(signer); // Same bytes as `addressEncoder.encode(signer.address)`.
-
[
@solana/codecs-data-structures,@solana/errors] #2089de1c63fThanks @latent-9! - Fix an infinite loop in thearray,set, andmapcodecs' sentinel and remainder decoding strategies: a zero-byte item codec (e.g.getStructCodec([])) can never advance past a sentinel boundary or the end of the byte array, so decoding used to push elements until the process ran out of memory. Zero-byte fixed-size item codecs are now rejected on both the encoding and decoding sides when used with the sentinel or remainder strategies, throwing a new error instead:SOLANA_ERROR__CODECS__UNEXPECTED_ZERO_FIXED_SIZE_ITEM_FOR_ARRAY_LIKE_SIZE_STRATEGY. They remain allowed when the collection size is explicit. -
[
@solana/errors] #21110be380eThanks @mcintyre94! - Add theSOLANA_ERROR__WALLET__INVALID_MESSAGE_SIGNATUREandSOLANA_ERROR__WALLET__INVALID_SIGN_IN_OUTPUTerror codes, thrown when a wallet returns a message signature or a sign-in output that fails verification. Their context carries the signing account'saddressand thewalletName.Also add the
SOLANA_ERROR__WALLET__INVALID_NUMBER_OF_OUTPUTSerror code, thrown when a wallet feature returns a different number of outputs than the number of inputs it was given. Its context carries theexpectedandactualnumber of outputs, thefeatureNameand thewalletName. -
[
@solana/errors,@solana/keys,@solana/webcrypto-ed25519-polyfill] #2095cfe1d62Thanks @mcintyre94! -verifySignature()now verifies strictly, regardless of whether the underlying WebCrypto implementation does so itself (Node.js, for instance, does not). It returnsfalsewhen either the public key or theRcomponent of the signature is a point of small order. Previously, trivially forged signatures could verify against small-order public keys such as11111111111111111111111111111111.BREAKING CHANGES
verifySignature()throws unless given an extractable public key. Checking the public key requires reading its bytes, so a non-extractable public key now causes it to throw aSolanaErrorwith codeSOLANA_ERROR__KEYS__VERIFICATION_REQUIRES_EXTRACTABLE_PUBLIC_KEY. The same error is thrown for a key that is not a public key, which WebCrypto never accepted for verification anyway (it threw anInvalidAccessError). Every public key produced by Kit is extractable; if you import one yourself, setextractabletotrue.- const publicKey = await crypto.subtle.importKey('raw', bytes, 'Ed25519', false, ['verify']); + const publicKey = await crypto.subtle.importKey('raw', bytes, 'Ed25519', true, ['verify']); await verifySignature(publicKey, signature, data);
getPublicKeyFromPrivateKey()always returns an extractable public key. Public keys are not secret, so this mirrors the behavior ofcrypto.subtle.generateKey(). Theextractableargument is deprecated and ignored.- const publicKey = await getPublicKeyFromPrivateKey(privateKey, true); + const publicKey = await getPublicKeyFromPrivateKey(privateKey);
The Ed25519 polyfill now also rejects public keys and signature
Rcomponents of small order, and opts out of@noble/ed25519's default ZIP-215 semantics. -
[
@solana/wallet-account-signer] #21129021e99Thanks @mcintyre94! -createMessageSignerFromWalletAccountnow verifies each signature returned by the wallet against the account's address and the message the wallet signed, andmodifyAndSignMessagesrejects withSOLANA_ERROR__WALLET__INVALID_MESSAGE_SIGNATUREif any of them is invalid. It also rejects withSOLANA_ERROR__WALLET__INVALID_NUMBER_OF_OUTPUTSif the wallet returns a different number of signed messages than it was asked to sign. The returned message content and signatures are copies of the wallet's output, so the wallet cannot change them after they are verified. Verifying signatures requires Ed25519 support in the WebCrypto API; in environments without it, install@solana/webcrypto-ed25519-polyfill.
Patch Changes
-
[
@solana/codecs-strings] #21177ea5132Thanks @Iamsohungrynow! -getBase16Encoderno longer drops the last digit of odd-length strings longer than one character:'abc'now encodes to[0xab, 0x0c]instead of[0xab, 0x00], andwriteadvances by the sizegetSizeFromValuereports. -
[
@solana/errors,@solana/sysvars,@solana/transaction-messages] #2110f47f025Thanks @mcintyre94! - Type-checkSolanaErrorcontexts in projects whose TypeScriptlibdoes not includeES2022.Error. TheSolanaErrorconstructor referenced the globalErrorOptionstype, which is unresolved without that lib, so withskipLibCheckenabled its context parameter silently becameanyand any context was accepted. Fixes the error contexts this was hiding:compileTransactionMessageanddecompileTransactionMessagenow report theunsupportedVersioninSOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, and theSlotHistorysysvar decoder now provides the expected context forSOLANA_ERROR__CODECS__INVALID_BYTE_LENGTHandSOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, so their messages no longer contain unfilled placeholders. -
[
@solana/fixed-points] #2102d7a1d10Thanks @lorisleiva! - Allow binary fixed-points whosefractionalBitsexceed theirtotalBits, e.g. an unsigned 8-bit value with 12 fractional bits representing values in[0, 1/16), consistently with decimal fixed-points whosedecimalsmay already exceed theirtotalBits. TheSOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITSerror is no longer thrown. -
[
@solana/plugin-interfaces] #210441896b7Thanks @lorisleiva! - FixClientWithTransactionPlanning,ClientWithTransactionSendingandClientWithTransactionSigningrejecting themaxInstructionsPerTransactionoption that transaction planners support per call. Their planning, sending and signing functions now accept it, making it possible to override the maximum number of instructions per transaction for a single request. Sending and signing functions only use it when their input needs to be planned first.await client.planTransactions(instructions, { maxInstructionsPerTransaction: 8 }); await client.sendTransactions(instructions, { maxInstructionsPerTransaction: 8 }); await client.signTransactions(instructions, { maxInstructionsPerTransaction: 8 });
-
[
@solana/rpc-graphql,@solana/rpc-parsed-types] #2101abfded6Thanks @ara-stock! - Fix the parsedepochRewardssysvar type to match what Agave returns. ThejsonParsedinfo hasactive,distributedRewards,distributionStartingBlockHeight,numPartitions,parentBlockhash,totalPointsandtotalRewards, and the reward amounts and points are strings. The old type described adistributionCompleteBlockHeightfield that Agave does not return, and typed the amounts asbigint. -
[
@solana/sysvars] #2116534ea5eThanks @Iamsohungrynow! - TheSysvarSlotHashesandSysvarRecentBlockhashesencoders/decoders now use theu64length prefix that these sysvar accounts actually have, instead of au32one. Previously every decoded entry was shifted by four bytes, so the slots, hashes and fees came back wrong.