From 2b7d98a9bd1297cbd3a18b6074fb83598d241410 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Fri, 2 Aug 2024 15:42:58 +0100 Subject: [PATCH] Add createKeyPairSignerFromPrivateKeyBytes helper --- .changeset/dry-glasses-roll.md | 5 +++++ packages/signers/README.md | 30 ++++++++++++++++++++++++++ packages/signers/src/keypair-signer.ts | 10 ++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .changeset/dry-glasses-roll.md diff --git a/.changeset/dry-glasses-roll.md b/.changeset/dry-glasses-roll.md new file mode 100644 index 000000000000..c36beea7ff86 --- /dev/null +++ b/.changeset/dry-glasses-roll.md @@ -0,0 +1,5 @@ +--- +'@solana/signers': patch +--- + +Add a `createKeyPairSignerFromPrivateKeyBytes` helper that compose `createKeyPairFromPrivateKeyBytes` and `createSignerFromKeyPair`. diff --git a/packages/signers/README.md b/packages/signers/README.md index 4075fd182083..d77bd4fb6c8b 100644 --- a/packages/signers/README.md +++ b/packages/signers/README.md @@ -316,6 +316,36 @@ import { generateKeyPairSigner } from '@solana/signers'; const myKeyPairSigner = await generateKeyPairSigner(); ``` +#### `createKeyPairSignerFromBytes()` + +A convenience function that creates a new KeyPair from a 64-bytes `Uint8Array` secret key and immediately creates a `KeyPairSigner` from it. + +```ts +import fs from 'fs'; +import { createKeyPairFromBytes } from '@solana/keys'; + +// Get bytes from local keypair file. +const keypairFile = fs.readFileSync('~/.config/solana/id.json'); +const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString())); + +// Create a KeyPairSigner from the bytes. +const { privateKey, publicKey } = await createKeyPairSignerFromBytes(keypairBytes); +``` + +#### `createKeyPairSignerFromPrivateKeyBytes()` + +A convenience function that creates a new KeyPair from a 32-bytes `Uint8Array` private key and immediately creates a `KeyPairSigner` from it. + +```ts +import { getUtf8Encoder } from '@solana/codecs-strings'; +import { createKeyPairFromPrivateKeyBytes } from '@solana/keys'; + +const message = getUtf8Encoder().encode('Hello, World!'); +const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message)); + +const derivedSigner = await createKeyPairSignerFromPrivateKeyBytes(seed); +``` + #### `isKeyPairSigner()` A type guard that returns `true` if the provided value is a `KeyPairSigner`. diff --git a/packages/signers/src/keypair-signer.ts b/packages/signers/src/keypair-signer.ts index 97ee97faf218..80ab07ffcbf0 100644 --- a/packages/signers/src/keypair-signer.ts +++ b/packages/signers/src/keypair-signer.ts @@ -1,7 +1,7 @@ import { Address, getAddressFromPublicKey } from '@solana/addresses'; import { ReadonlyUint8Array } from '@solana/codecs-core'; import { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@solana/errors'; -import { createKeyPairFromBytes, generateKeyPair, signBytes } from '@solana/keys'; +import { createKeyPairFromBytes, createKeyPairFromPrivateKeyBytes, generateKeyPair, signBytes } from '@solana/keys'; import { partiallySignTransaction } from '@solana/transactions'; import { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer'; @@ -73,3 +73,11 @@ export async function createKeyPairSignerFromBytes( ): Promise { return await createSignerFromKeyPair(await createKeyPairFromBytes(bytes, extractable)); } + +/** Creates a signer capable of signing messages and transactions using the 32 bytes of a private key. */ +export async function createKeyPairSignerFromPrivateKeyBytes( + bytes: ReadonlyUint8Array, + extractable?: boolean, +): Promise { + return await createSignerFromKeyPair(await createKeyPairFromPrivateKeyBytes(bytes, extractable)); +}