All files / src/clarity deserialize.ts

94.82% Statements 55/58
90.9% Branches 20/22
50% Functions 1/2
94.64% Lines 53/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 11721x 21x 21x 21x 21x 21x       21x 21x 21x 21x 21x               21x     21x       118x 4x 4x     114x 15x   99x   118x           1x     47x     8x 8x     11x     4x     24x 24x     3x 3x 3x     1x     1x     1x     3x     3x 3x 3x 35x   3x     7x 7x 7x 31x 31x     31x   7x     3x 3x 3x     1x 1x 1x                
import { ClarityType } from './common/constants';
import { falseCV, trueCV } from './types/booleanCV';
import { intCV, uintCV } from './types/intCV';
import { bufferCV } from './types/bufferCV';
import { noneCV, someCV } from './types/optionalCV';
import { responseErrorCV, responseOkCV } from './types/responseCV';
import {
  contractPrincipalCVFromAddress,
  standardPrincipalCVFromAddress,
} from './types/principalCV';
import { listCV } from './types/listCV';
import { tupleCV } from './types/tupleCV';
import { stringAsciiCV, stringUtf8CV } from './types/stringCV';
import { deserializeAddress, deserializeLPString } from './common/utils';
 
import {
  BufferReader,
  bytesToAscii,
  bytesToUtf8,
  hexToBytes,
  DeserializationError,
} from 'micro-stacks/common';
import { ClarityValue } from './clarity-value/types';
 
export function deserializeCV<T extends ClarityValue = ClarityValue>(
  serializedClarityValue: BufferReader | Uint8Array | string
): T {
  let bufferReader: BufferReader;
  if (typeof serializedClarityValue === 'string') {
    const hasHexPrefix = serializedClarityValue.slice(0, 2).toLowerCase() === '0x';
    bufferReader = new BufferReader(
      hexToBytes(hasHexPrefix ? serializedClarityValue.slice(2) : serializedClarityValue)
    );
  } else if (serializedClarityValue instanceof Uint8Array) {
    bufferReader = new BufferReader(serializedClarityValue);
  } else {
    bufferReader = serializedClarityValue;
  }
  const type = bufferReader.readUInt8Enum(ClarityType, n => {
    throw new DeserializationError(`Cannot recognize Clarity Type: ${n}`);
  });
 
  switch (type) {
    case ClarityType.Int:
      return intCV(bufferReader.readBuffer(16)) as T;
 
    case ClarityType.UInt:
      return uintCV(bufferReader.readBuffer(16)) as T;
 
    case ClarityType.Buffer:
      const bufferLength = bufferReader.readUInt32BE();
      return bufferCV(bufferReader.readBuffer(bufferLength)) as T;
 
    case ClarityType.BoolTrue:
      return trueCV() as T;
 
    case ClarityType.BoolFalse:
      return falseCV() as T;
 
    case ClarityType.PrincipalStandard:
      const sAddress = deserializeAddress(bufferReader);
      return standardPrincipalCVFromAddress(sAddress) as T;
 
    case ClarityType.PrincipalContract:
      const cAddress = deserializeAddress(bufferReader);
      const contractName = deserializeLPString(bufferReader);
      return contractPrincipalCVFromAddress(cAddress, contractName) as T;
 
    case ClarityType.ResponseOk:
      return responseOkCV(deserializeCV(bufferReader)) as T;
 
    case ClarityType.ResponseErr:
      return responseErrorCV(deserializeCV(bufferReader)) as T;
 
    case ClarityType.OptionalNone:
      return noneCV() as T;
 
    case ClarityType.OptionalSome:
      return someCV(deserializeCV(bufferReader)) as T;
 
    case ClarityType.List:
      const listLength = bufferReader.readUInt32BE();
      const listContents: ClarityValue[] = [];
      for (let i = 0; i < listLength; i++) {
        listContents.push(deserializeCV(bufferReader));
      }
      return listCV(listContents) as T;
 
    case ClarityType.Tuple:
      const tupleLength = bufferReader.readUInt32BE();
      const tupleContents: { [key: string]: ClarityValue } = {};
      for (let i = 0; i < tupleLength; i++) {
        const clarityName = deserializeLPString(bufferReader).content;
        Iif (clarityName === undefined) {
          throw new DeserializationError('"content" is undefined');
        }
        tupleContents[clarityName] = deserializeCV(bufferReader);
      }
      return tupleCV(tupleContents) as T;
 
    case ClarityType.StringASCII:
      const asciiStrLen = bufferReader.readUInt32BE();
      const asciiStr = bytesToAscii(bufferReader.readBuffer(asciiStrLen));
      return stringAsciiCV(asciiStr) as T;
 
    case ClarityType.StringUTF8:
      const utf8StrLen = bufferReader.readUInt32BE();
      const utf8Str = bytesToUtf8(bufferReader.readBuffer(utf8StrLen));
      return stringUtf8CV(utf8Str) as T;
 
    default:
      throw new DeserializationError(
        'Unable to deserialize Clarity Value from buffer. Could not find valid Clarity Type.'
      );
  }
}