diff --git a/src/wallets/solana/solanaClient.test.ts b/src/wallets/solana/solanaClient.test.ts new file mode 100644 index 000000000..90c3190de --- /dev/null +++ b/src/wallets/solana/solanaClient.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from 'vitest' + +import { UserInputValidationError } from '../../errors' +import { SolanaClient } from './solanaClient' + +describe('SolanaClient.importAccount', () => { + it('rejects odd-length hex private keys before encryption', async () => { + const client = new SolanaClient() + + await expect( + client.importAccount({ privateKey: `0x${'a'.repeat(63)}` }), + ).rejects.toThrow(UserInputValidationError) + await expect( + client.importAccount({ privateKey: `0x${'a'.repeat(63)}` }), + ).rejects.toThrow( + 'Private key hex string must contain an even number of characters', + ) + }) +}) diff --git a/src/wallets/solana/solanaClient.ts b/src/wallets/solana/solanaClient.ts index f36caa6bc..d90331df0 100644 --- a/src/wallets/solana/solanaClient.ts +++ b/src/wallets/solana/solanaClient.ts @@ -225,9 +225,19 @@ export class SolanaClient { if (!/^[0-9a-fA-F]+$/.test(hex)) { throw new UserInputValidationError('Invalid hex string') } + if (hex.length % 2 !== 0) { + throw new UserInputValidationError( + 'Private key hex string must contain an even number of characters', + ) + } privateKeyBytes = Uint8Array.from(Buffer.from(hex, 'hex')) } else if (/^[0-9a-fA-F]+$/.test(options.privateKey)) { // Hex format without prefix + if (options.privateKey.length % 2 !== 0) { + throw new UserInputValidationError( + 'Private key hex string must contain an even number of characters', + ) + } privateKeyBytes = Uint8Array.from(Buffer.from(options.privateKey, 'hex')) } else { // Assume base58 format (standard Solana format)