Skip to content

Commit

Permalink
fix: Consolidate is prefixed boolean methods
Browse files Browse the repository at this point in the history
  • Loading branch information
janniks committed Sep 17, 2024
1 parent 28fd7a2 commit 9a4e513
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 46 deletions.
75 changes: 43 additions & 32 deletions packages/transactions/src/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import {
} from '@noble/secp256k1';
import {
bytesToHex,
concatArray,
hexToBigInt,
hexToBytes,
intToHex,
isInstance,
parseRecoverableSignatureVrs,
PRIVATE_KEY_COMPRESSED_LENGTH,
PrivateKey,
Expand All @@ -31,14 +29,7 @@ import {
} from '@stacks/network';
import { c32address } from 'c32check';
import { addressHashModeToVersion } from './address';
import { BytesReader } from './BytesReader';
import {
AddressHashMode,
AddressVersion,
COMPRESSED_PUBKEY_LENGTH_BYTES,
PubKeyEncoding,
UNCOMPRESSED_PUBKEY_LENGTH_BYTES,
} from './constants';
import { AddressHashMode, AddressVersion, PubKeyEncoding } from './constants';
import { hash160, hashP2PKH } from './utils';
import {
addressFromVersionHash,
Expand Down Expand Up @@ -124,23 +115,39 @@ export function privateKeyToHex(publicKey: PublicKey): string {
}
export const publicKeyToHex = privateKeyToHex;

/**
* Checks if a private key is compressed
*
* @example
* ```ts
* isPrivateKeyCompressed('64879bd015b0fbc19a798040b399b59c3c756cc79eaa9d24d18e66106ad7ee4801'); // true
* isPrivateKeyCompressed('64879bd015b0fbc19a798040b399b59c3c756cc79eaa9d24d18e66106ad7ee48'); // false
* ```
*/
export const isPrivateKeyCompressed = privateKeyIsCompressed;

/** @deprecated Use {@link isPrivateKeyCompressed} instead */
export function privateKeyIsCompressed(privateKey: PrivateKey): boolean {
const length = typeof privateKey === 'string' ? privateKey.length / 2 : privateKey.byteLength;
return length === PRIVATE_KEY_COMPRESSED_LENGTH;
}

/**
* Checks if a public key is compressed
*
* @example
* ```ts
* isPublicKeyCompressed('0367b23680c33a3adc784b80952f9bba83169d84c6567f49c9a92f7cc9c9b6f61b'); // true
* isPublicKeyCompressed('04171ee91c13f2007bd22c3280987d113e9ffdb2f10631783473899868e67dcdb876f2be26558ea1d4194a96a3707aff085c96a643d43e02c0e9e67c5d47a7dac6'); // false
* ```
*/
export const isPublicKeyCompressed = publicKeyIsCompressed;

/** @deprecated Use {@link isPublicKeyCompressed} instead */
export function publicKeyIsCompressed(publicKey: PublicKey): boolean {
return !publicKeyToHex(publicKey).startsWith('04');
}

export function serializePublicKey(key: PublicKeyWire): string {
return bytesToHex(serializePublicKeyBytes(key));
}
/** @ignore */
export function serializePublicKeyBytes(key: PublicKeyWire): Uint8Array {
return key.data.slice();
}

/**
* Get the public key from a private key.
* Allows for "compressed" and "uncompressed" private keys.
Expand All @@ -153,28 +160,32 @@ export function privateKeyToPublic(privateKey: PrivateKey): string {
return bytesToHex(nobleGetPublicKey(privateKey.slice(0, 32), isCompressed));
}

/**
* Compresses a public key
*
* @example
* ```ts
* compressPublicKey('04171ee91c13f2007bd22c3280987d113e9ffdb2f10631783473899868e67dcdb876f2be26558ea1d4194a96a3707aff085c96a643d43e02c0e9e67c5d47a7dac6');
* // '0367b23680c33a3adc784b80952f9bba83169d84c6567f49c9a92f7cc9c9b6f61b'
* ```
*/
export function compressPublicKey(publicKey: PublicKey): string {
return Point.fromHex(publicKeyToHex(publicKey)).toHex(true);
}

/**
* Uncompresses a public key
*
* @example
* ```ts
* uncompressPublicKey('0367b23680c33a3adc784b80952f9bba83169d84c6567f49c9a92f7cc9c9b6f61b');
* // '04171ee91c13f2007bd22c3280987d113e9ffdb2f10631783473899868e67dcdb876f2be26558ea1d4194a96a3707aff085c96a643d43e02c0e9e67c5d47a7dac6'
* ```
*/
export function uncompressPublicKey(publicKey: PublicKey): string {
return Point.fromHex(publicKeyToHex(publicKey)).toHex(false);
}

export function deserializePublicKey(serialized: string): PublicKeyWire {
return deserializePublicKeyBytes(hexToBytes(serialized));
}
/** @ignore */
export function deserializePublicKeyBytes(serialized: Uint8Array | BytesReader): PublicKeyWire {
const bytesReader = isInstance(serialized, BytesReader)
? serialized
: new BytesReader(serialized);
const fieldId = bytesReader.readUInt8();
const keyLength =
fieldId === 4 ? UNCOMPRESSED_PUBKEY_LENGTH_BYTES : COMPRESSED_PUBKEY_LENGTH_BYTES;
return createStacksPublicKey(concatArray([fieldId, bytesReader.readBytes(keyLength)]));
}

// todo: double-check for deduplication, rename!
export function makeRandomPrivKey(): string {
return bytesToHex(utils.randomPrivateKey());
Expand Down
3 changes: 2 additions & 1 deletion packages/transactions/src/wire/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { TransactionVersion } from '@stacks/network';
import { c32address } from 'c32check';
import { addressHashModeToVersion } from '../address';
import { AddressHashMode, AddressVersion, PayloadType } from '../constants';
import { publicKeyIsCompressed, serializePublicKeyBytes } from '../keys';
import { publicKeyIsCompressed } from '../keys';
import { AssetString } from '../types';
import { hashP2PKH, hashP2SH, hashP2WPKH, hashP2WSH } from '../utils';
import { createAsset, createContractPrincipal, createStandardPrincipal } from './create';
import { serializePublicKeyBytes } from './serialization';
import {
AddressWire,
AssetWire,
Expand Down
33 changes: 26 additions & 7 deletions packages/transactions/src/wire/serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import {
AuthFieldType,
COINBASE_BYTES_LENGTH,
COMPRESSED_PUBKEY_LENGTH_BYTES,
ClarityVersion,
FungibleConditionCode,
MEMO_MAX_LENGTH_BYTES,
Expand All @@ -35,16 +36,11 @@ import {
PubKeyEncoding,
RECOVERABLE_ECDSA_SIG_LENGTH_BYTES,
TenureChangeCause,
UNCOMPRESSED_PUBKEY_LENGTH_BYTES,
VRF_PROOF_BYTES_LENGTH,
} from '../constants';
import { DeserializationError, SerializationError } from '../errors';
import {
compressPublicKey,
createStacksPublicKey,
deserializePublicKeyBytes,
serializePublicKeyBytes,
uncompressPublicKey,
} from '../keys';
import { compressPublicKey, createStacksPublicKey, uncompressPublicKey } from '../keys';
import { rightPadHexToLength } from '../utils';
import {
createCoinbasePayload,
Expand All @@ -71,6 +67,7 @@ import {
PayloadWire,
PostConditionPrincipalWire,
PostConditionWire,
PublicKeyWire,
StacksWire,
StacksWireType,
StandardPrincipalWire,
Expand Down Expand Up @@ -698,3 +695,25 @@ export function serializeTransactionAuthFieldBytes(field: TransactionAuthFieldWi

return concatArray(bytesArray);
}

export function serializePublicKey(key: PublicKeyWire): string {
return bytesToHex(serializePublicKeyBytes(key));
}
/** @ignore */
export function serializePublicKeyBytes(key: PublicKeyWire): Uint8Array {
return key.data.slice();
}

export function deserializePublicKey(serialized: string): PublicKeyWire {
return deserializePublicKeyBytes(hexToBytes(serialized));
}
/** @ignore */
export function deserializePublicKeyBytes(serialized: Uint8Array | BytesReader): PublicKeyWire {
const bytesReader = isInstance(serialized, BytesReader)
? serialized
: new BytesReader(serialized);
const fieldId = bytesReader.readUInt8();
const keyLength =
fieldId === 4 ? UNCOMPRESSED_PUBKEY_LENGTH_BYTES : COMPRESSED_PUBKEY_LENGTH_BYTES;
return createStacksPublicKey(concatArray([fieldId, bytesReader.readBytes(keyLength)]));
}
8 changes: 2 additions & 6 deletions packages/transactions/tests/transaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@ import {
FungibleConditionCode,
PostConditionMode,
} from '../src/constants';
import {
createStacksPublicKey,
privateKeyToPublic,
publicKeyToHex,
serializePublicKeyBytes,
} from '../src/keys';
import { createStacksPublicKey, privateKeyToPublic, publicKeyToHex } from '../src/keys';

import {
CoinbasePayloadToAltRecipient,
Expand All @@ -34,6 +29,7 @@ import {
createLPList,
createStandardPrincipal,
createTokenTransferPayload,
serializePublicKeyBytes,
} from '../src';
import { postConditionToWire } from '../src/postcondition';
import { TransactionSigner } from '../src/signer';
Expand Down

0 comments on commit 9a4e513

Please sign in to comment.