import { BufferReader } from './bufferReader' ; import { DeserializationError } from './errors' ; import { PubKeyEncoding , RECOVERABLE_ECDSA_SIG_LENGTH_BYTES , StacksMessageType } from './constants' ; import { compressPublicKey , deserializePublicKey , serializePublicKey , StacksPublicKey , } from './keys' ; import { createMessageSignature , MessageSignature } from './common' ; import { Buffer } from '@stacks/common' ; import { BufferArray } from './utils' ; export enum AuthFieldType { PublicKeyCompressed = 0x00 , PublicKeyUncompressed = 0x01 , SignatureCompressed = 0x02 , SignatureUncompressed = 0x03 } export interface TransactionAuthField { type : StacksMessageType . TransactionAuthField ; pubKeyEncoding : PubKeyEncoding ; contents : TransactionAuthFieldContents ; } export type TransactionAuthFieldContents = StacksPublicKey | MessageSignature ; export function deserializeMessageSignature ( bufferReader ) { return createMessageSignature ( bufferReader . readBuffer ( RECOVERABLE_ECDSA_SIG_LENGTH_BYTES ) . toString ( 'hex' ) ) ; } export interface TransactionAuthField { type : StacksMessageType . TransactionAuthField ; pubKeyEncoding : PubKeyEncoding ; contents : TransactionAuthFieldContents ; } export function createTransactionAuthField ( pubKeyEncoding , contents ) { return { pubKeyEncoding , type : StacksMessageType . TransactionAuthField , contents , } ; } export function deserializeTransactionAuthField ( bufferReader ) { const authFieldType = bufferReader . readUInt8Enum ( AuthFieldType , n => { throw new DeserializationError ( `Could not read ${ n } as AuthFieldType` ) ; } ) ; switch ( authFieldType ) { case AuthFieldType . PublicKeyCompressed : return createTransactionAuthField ( PubKeyEncoding . Compressed , deserializePublicKey ( bufferReader ) ) ; case AuthFieldType . PublicKeyUncompressed : return createTransactionAuthField ( PubKeyEncoding . Uncompressed , deserializePublicKey ( bufferReader ) ) ; case AuthFieldType . SignatureCompressed : return createTransactionAuthField ( PubKeyEncoding . Compressed , deserializeMessageSignature ( bufferReader ) ) ; case AuthFieldType . SignatureUncompressed : return createTransactionAuthField ( PubKeyEncoding . Uncompressed , deserializeMessageSignature ( bufferReader ) ) ; default : throw new Error ( `Unknown auth field type: ${ JSON . stringify ( authFieldType ) }` ) ; } } export function serializeMessageSignature ( messageSignature ) { const bufferArray = new BufferArray ( ) ; bufferArray . appendHexString ( messageSignature . data ) ; return bufferArray . concatBuffer ( ) ; } export function serializeTransactionAuthField ( field ) { const bufferArray = new BufferArray ( ) ; switch ( field . contents . type ) { case StacksMessageType . PublicKey : if ( field . pubKeyEncoding == PubKeyEncoding . Compressed ) { bufferArray . appendByte ( AuthFieldType . PublicKeyCompressed ) ; bufferArray . push ( serializePublicKey ( field . contents ) ) ; } else { bufferArray . appendByte ( AuthFieldType . PublicKeyUncompressed ) ; bufferArray . push ( serializePublicKey ( compressPublicKey ( field . contents . data ) ) ) ; } break ; case StacksMessageType . MessageSignature : if ( field . pubKeyEncoding == PubKeyEncoding . Compressed ) { bufferArray . appendByte ( AuthFieldType . SignatureCompressed ) ; } else { bufferArray . appendByte ( AuthFieldType . SignatureUncompressed ) ; } bufferArray . push ( serializeMessageSignature ( field . contents ) ) ; break ; } return bufferArray . concatBuffer ( ) ; }