diff --git a/.changeset/stale-turtles-hang.md b/.changeset/stale-turtles-hang.md new file mode 100644 index 000000000000..f3744b7e1663 --- /dev/null +++ b/.changeset/stale-turtles-hang.md @@ -0,0 +1,6 @@ +--- +"@solana/signers": patch +"@solana/keys": patch +--- + +Allow creating keypairs and keys from ReadonlyUint8Array diff --git a/packages/keys/src/__typetests__/key-pair-typetests.ts b/packages/keys/src/__typetests__/key-pair-typetests.ts new file mode 100644 index 000000000000..367b1cdc166d --- /dev/null +++ b/packages/keys/src/__typetests__/key-pair-typetests.ts @@ -0,0 +1,6 @@ +import { ReadonlyUint8Array } from '@solana/codecs-core'; + +import { createKeyPairFromBytes } from '../key-pair'; + +createKeyPairFromBytes(new Uint8Array()) satisfies Promise; +createKeyPairFromBytes(new Uint8Array() as ReadonlyUint8Array) satisfies Promise; diff --git a/packages/keys/src/__typetests__/private-key-typetests.ts b/packages/keys/src/__typetests__/private-key-typetests.ts new file mode 100644 index 000000000000..8bf613733857 --- /dev/null +++ b/packages/keys/src/__typetests__/private-key-typetests.ts @@ -0,0 +1,6 @@ +import { ReadonlyUint8Array } from '@solana/codecs-core'; + +import { createPrivateKeyFromBytes } from '../private-key'; + +createPrivateKeyFromBytes(new Uint8Array()) satisfies Promise; +createPrivateKeyFromBytes(new Uint8Array() as ReadonlyUint8Array) satisfies Promise; diff --git a/packages/keys/src/__typetests__/coercions-typetests.ts b/packages/keys/src/__typetests__/signatures-typetests.ts similarity index 100% rename from packages/keys/src/__typetests__/coercions-typetests.ts rename to packages/keys/src/__typetests__/signatures-typetests.ts diff --git a/packages/keys/src/key-pair.ts b/packages/keys/src/key-pair.ts index 32c3264e8510..3eb0736b5311 100644 --- a/packages/keys/src/key-pair.ts +++ b/packages/keys/src/key-pair.ts @@ -1,4 +1,5 @@ import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions'; +import { ReadonlyUint8Array } from '@solana/codecs-core'; import { SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY, @@ -18,7 +19,7 @@ export async function generateKeyPair(): Promise { return keyPair as CryptoKeyPair; } -export async function createKeyPairFromBytes(bytes: Uint8Array, extractable?: boolean): Promise { +export async function createKeyPairFromBytes(bytes: ReadonlyUint8Array, extractable?: boolean): Promise { assertPRNGIsAvailable(); if (bytes.byteLength !== 64) { diff --git a/packages/keys/src/private-key.ts b/packages/keys/src/private-key.ts index ec4e2f0c49e4..c623f46306f2 100644 --- a/packages/keys/src/private-key.ts +++ b/packages/keys/src/private-key.ts @@ -1,6 +1,7 @@ +import { ReadonlyUint8Array } from '@solana/codecs-core'; import { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors'; -function addPkcs8Header(bytes: Uint8Array): Uint8Array { +function addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array { // prettier-ignore return new Uint8Array([ /** @@ -37,7 +38,7 @@ function addPkcs8Header(bytes: Uint8Array): Uint8Array { ]); } -export async function createPrivateKeyFromBytes(bytes: Uint8Array, extractable?: boolean): Promise { +export async function createPrivateKeyFromBytes(bytes: ReadonlyUint8Array, extractable?: boolean): Promise { const actualLength = bytes.byteLength; if (actualLength !== 32) { throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, { diff --git a/packages/signers/src/keypair-signer.ts b/packages/signers/src/keypair-signer.ts index 1cd7dc0661af..3b2a764e03c0 100644 --- a/packages/signers/src/keypair-signer.ts +++ b/packages/signers/src/keypair-signer.ts @@ -3,6 +3,7 @@ import { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@so import { createKeyPairFromBytes, generateKeyPair, signBytes } from '@solana/keys'; import { partiallySignTransaction } from '@solana/transactions'; +import { ReadonlyUint8Array } from '../../codecs-core/dist/types'; import { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer'; import { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer'; @@ -66,6 +67,9 @@ export async function generateKeyPairSigner(): Promise { } /** Creates a signer capable of signing messages and transactions using the 64 bytes of a KeyPair. */ -export async function createKeyPairSignerFromBytes(bytes: Uint8Array, extractable?: boolean): Promise { +export async function createKeyPairSignerFromBytes( + bytes: ReadonlyUint8Array, + extractable?: boolean, +): Promise { return await createSignerFromKeyPair(await createKeyPairFromBytes(bytes, extractable)); }