diff --git a/.changeset/tall-bobcats-marry.md b/.changeset/tall-bobcats-marry.md new file mode 100644 index 000000000..21ccb6212 --- /dev/null +++ b/.changeset/tall-bobcats-marry.md @@ -0,0 +1,9 @@ +--- +'@solana/codecs-numbers': patch +'@solana/codecs-strings': patch +'@solana/codecs-core': patch +'@solana/compat': patch +'@solana/keys': patch +--- + +Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise diff --git a/packages/codecs-core/src/codec.ts b/packages/codecs-core/src/codec.ts index b26184434..c3a02b398 100644 --- a/packages/codecs-core/src/codec.ts +++ b/packages/codecs-core/src/codec.ts @@ -24,7 +24,7 @@ export type Offset = number; */ type BaseEncoder = { /** Encode the provided value and return the encoded bytes directly. */ - readonly encode: (value: TFrom) => ReadonlyUint8Array; + readonly encode: (value: TFrom) => ReadonlyUint8Array; /** * Writes the encoded value into the provided byte array at the given offset. * Returns the offset of the next byte after the encoded value. diff --git a/packages/codecs-core/src/readonly-uint8array.ts b/packages/codecs-core/src/readonly-uint8array.ts index 518ce4109..d4b66c811 100644 --- a/packages/codecs-core/src/readonly-uint8array.ts +++ b/packages/codecs-core/src/readonly-uint8array.ts @@ -11,7 +11,8 @@ * bytes[0] = 42; // Type error: Cannot assign to '0' because it is a read-only property. * ``` */ -export interface ReadonlyUint8Array extends Omit { +export interface ReadonlyUint8Array + extends Omit, TypedArrayMutableProperties> { readonly [n: number]: number; } diff --git a/packages/codecs-strings/src/base64.ts b/packages/codecs-strings/src/base64.ts index 2197631a6..8a310a6e0 100644 --- a/packages/codecs-strings/src/base64.ts +++ b/packages/codecs-strings/src/base64.ts @@ -2,6 +2,7 @@ import { combineCodec, createDecoder, createEncoder, + toArrayBuffer, transformDecoder, transformEncoder, VariableSizeCodec, @@ -112,7 +113,7 @@ export const getBase64Decoder = (): VariableSizeDecoder => { if (__NODEJS__) { return createDecoder({ - read: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length], + read: (bytes, offset = 0) => [Buffer.from(toArrayBuffer(bytes), offset).toString('base64'), bytes.length], }); } diff --git a/packages/compat/src/__tests__/instruction-test.ts b/packages/compat/src/__tests__/instruction-test.ts index c3d5dba2c..de6ddc2fe 100644 --- a/packages/compat/src/__tests__/instruction-test.ts +++ b/packages/compat/src/__tests__/instruction-test.ts @@ -1,7 +1,5 @@ import '@solana/test-matchers/toBeFrozenObject'; -import { ImplicitArrayBuffer } from 'node:buffer'; - import { address } from '@solana/addresses'; import { AccountRole, Instruction } from '@solana/instructions'; import { PublicKey, TransactionInstruction } from '@solana/web3.js'; @@ -9,13 +7,11 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { fromLegacyPublicKey } from '../address'; import { fromLegacyTransactionInstruction } from '../instruction'; -function toLegacyByteArrayAppropriateForPlatform( - data: ImplicitArrayBuffer, -) { +function toLegacyByteArrayAppropriateForPlatform(data: Uint8Array) { if (__NODEJS__) { return Buffer.from(data); } else { - return new Uint8Array(data as TArrayBuffer) as Buffer; + return new Uint8Array(data) as Buffer; } } diff --git a/packages/keys/src/private-key.ts b/packages/keys/src/private-key.ts index 9f673e026..f9a87aa3e 100644 --- a/packages/keys/src/private-key.ts +++ b/packages/keys/src/private-key.ts @@ -3,7 +3,7 @@ import { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from import { ED25519_ALGORITHM_IDENTIFIER } from './algorithm'; -function addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array { +function addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array { // prettier-ignore return new Uint8Array([ /** diff --git a/packages/keys/src/signatures.ts b/packages/keys/src/signatures.ts index 3e8b7f81c..7c883532f 100644 --- a/packages/keys/src/signatures.ts +++ b/packages/keys/src/signatures.ts @@ -1,5 +1,5 @@ import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions'; -import { Encoder, ReadonlyUint8Array } from '@solana/codecs-core'; +import { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core'; import { getBase58Encoder } from '@solana/codecs-strings'; import { SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, @@ -185,7 +185,7 @@ export function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): pu */ export async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise { assertSigningCapabilityIsAvailable(); - const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, data); + const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data)); return new Uint8Array(signedData) as SignatureBytes; } @@ -249,5 +249,5 @@ export async function verifySignature( data: ReadonlyUint8Array, ): Promise { assertVerificationCapabilityIsAvailable(); - return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, signature, data); + return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data)); }