Skip to content

Commit b47cda9

Browse files
committed
refactor!: change clarity types to be human readable
BREAKING CHANGE: The `ClarityType` was changed to a readable string, from the previous Number type. This makes it easier to read and construct types when debugging.
1 parent 7f8a388 commit b47cda9

File tree

15 files changed

+109
-135
lines changed

15 files changed

+109
-135
lines changed
Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1+
/**
2+
* Clarity type names used for the human-readable representation of Clarity values
3+
*/
4+
export enum ClarityType {
5+
Int = 'int',
6+
UInt = 'uint',
7+
Buffer = 'buffer',
8+
BoolTrue = 'true',
9+
BoolFalse = 'false',
10+
PrincipalStandard = 'address',
11+
PrincipalContract = 'contract',
12+
ResponseOk = 'ok',
13+
ResponseErr = 'err',
14+
OptionalNone = 'none',
15+
OptionalSome = 'some',
16+
List = 'list',
17+
Tuple = 'tuple',
18+
StringASCII = 'ascii',
19+
StringUTF8 = 'utf8',
20+
}
21+
122
/**
223
* Type IDs corresponding to each of the Clarity value types as described here:
324
* {@link https://github.com/blockstack/blockstack-core/blob/sip/sip-005/sip/sip-005-blocks-and-transactions.md#clarity-value-representation}
425
*/
5-
export enum ClarityType {
6-
Int = 0x00,
7-
UInt = 0x01,
8-
Buffer = 0x02,
9-
BoolTrue = 0x03,
10-
BoolFalse = 0x04,
11-
PrincipalStandard = 0x05,
12-
PrincipalContract = 0x06,
13-
ResponseOk = 0x07,
14-
ResponseErr = 0x08,
15-
OptionalNone = 0x09,
16-
OptionalSome = 0x0a,
17-
List = 0x0b,
18-
Tuple = 0x0c,
19-
StringASCII = 0x0d,
20-
StringUTF8 = 0x0e,
26+
export enum ClarityWireType {
27+
int = 0x00,
28+
uint = 0x01,
29+
buffer = 0x02,
30+
true = 0x03,
31+
false = 0x04,
32+
address = 0x05,
33+
contract = 0x06,
34+
ok = 0x07,
35+
err = 0x08,
36+
none = 0x09,
37+
some = 0x0a,
38+
list = 0x0b,
39+
tuple = 0x0c,
40+
ascii = 0x0d,
41+
utf8 = 0x0e,
42+
}
43+
44+
/** @ignore internal for now */
45+
export function clarityTypeToByte(type: ClarityType): ClarityWireType {
46+
return ClarityWireType[type];
47+
}
48+
49+
/** @ignore internal for now */
50+
export function clarityByteToType(wireType: ClarityWireType): ClarityType {
51+
return ClarityWireType[wireType] as ClarityType; // numerical enums are bidirectional in TypeScript
2152
}

packages/transactions/src/clarity/deserialize.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
ClarityType,
2+
ClarityWireType,
33
ClarityValue,
44
intCV,
55
uintCV,
@@ -43,7 +43,7 @@ import { bytesToAscii, bytesToUtf8, hexToBytes } from '@stacks/common';
4343
* @see
4444
* {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples}
4545
*/
46-
export default function deserializeCV<T extends ClarityValue = ClarityValue>(
46+
export function deserializeCV<T extends ClarityValue = ClarityValue>(
4747
serializedClarityValue: BytesReader | Uint8Array | string
4848
): T {
4949
let bytesReader: BytesReader;
@@ -57,57 +57,57 @@ export default function deserializeCV<T extends ClarityValue = ClarityValue>(
5757
} else {
5858
bytesReader = serializedClarityValue;
5959
}
60-
const type = bytesReader.readUInt8Enum(ClarityType, n => {
60+
const type = bytesReader.readUInt8Enum(ClarityWireType, n => {
6161
throw new DeserializationError(`Cannot recognize Clarity Type: ${n}`);
6262
});
6363

6464
switch (type) {
65-
case ClarityType.Int:
65+
case ClarityWireType.int:
6666
return intCV(bytesReader.readBytes(16)) as T;
6767

68-
case ClarityType.UInt:
68+
case ClarityWireType.uint:
6969
return uintCV(bytesReader.readBytes(16)) as T;
7070

71-
case ClarityType.Buffer:
71+
case ClarityWireType.buffer:
7272
const bufferLength = bytesReader.readUInt32BE();
7373
return bufferCV(bytesReader.readBytes(bufferLength)) as T;
7474

75-
case ClarityType.BoolTrue:
75+
case ClarityWireType.true:
7676
return trueCV() as T;
7777

78-
case ClarityType.BoolFalse:
78+
case ClarityWireType.false:
7979
return falseCV() as T;
8080

81-
case ClarityType.PrincipalStandard:
81+
case ClarityWireType.address:
8282
const sAddress = deserializeAddress(bytesReader);
8383
return standardPrincipalCVFromAddress(sAddress) as T;
8484

85-
case ClarityType.PrincipalContract:
85+
case ClarityWireType.contract:
8686
const cAddress = deserializeAddress(bytesReader);
8787
const contractName = deserializeLPString(bytesReader);
8888
return contractPrincipalCVFromAddress(cAddress, contractName) as T;
8989

90-
case ClarityType.ResponseOk:
90+
case ClarityWireType.ok:
9191
return responseOkCV(deserializeCV(bytesReader)) as T;
9292

93-
case ClarityType.ResponseErr:
93+
case ClarityWireType.err:
9494
return responseErrorCV(deserializeCV(bytesReader)) as T;
9595

96-
case ClarityType.OptionalNone:
96+
case ClarityWireType.none:
9797
return noneCV() as T;
9898

99-
case ClarityType.OptionalSome:
99+
case ClarityWireType.some:
100100
return someCV(deserializeCV(bytesReader)) as T;
101101

102-
case ClarityType.List:
102+
case ClarityWireType.list:
103103
const listLength = bytesReader.readUInt32BE();
104104
const listContents: ClarityValue[] = [];
105105
for (let i = 0; i < listLength; i++) {
106106
listContents.push(deserializeCV(bytesReader));
107107
}
108108
return listCV(listContents) as T;
109109

110-
case ClarityType.Tuple:
110+
case ClarityWireType.tuple:
111111
const tupleLength = bytesReader.readUInt32BE();
112112
const tupleContents: { [key: string]: ClarityValue } = {};
113113
for (let i = 0; i < tupleLength; i++) {
@@ -119,12 +119,12 @@ export default function deserializeCV<T extends ClarityValue = ClarityValue>(
119119
}
120120
return tupleCV(tupleContents) as T;
121121

122-
case ClarityType.StringASCII:
122+
case ClarityWireType.ascii:
123123
const asciiStrLen = bytesReader.readUInt32BE();
124124
const asciiStr = bytesToAscii(bytesReader.readBytes(asciiStrLen));
125125
return stringAsciiCV(asciiStr) as T;
126126

127-
case ClarityType.StringUTF8:
127+
case ClarityWireType.utf8:
128128
const utf8StrLen = bytesReader.readUInt32BE();
129129
const utf8Str = bytesToUtf8(bytesReader.readBytes(utf8StrLen));
130130
return stringUtf8CV(utf8Str) as T;
Lines changed: 15 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import {
1+
// todo: use `export *` for more exports here
2+
3+
export {
24
ClarityValue,
35
getCVTypeString,
46
cvToString,
57
cvToJSON,
68
cvToValue,
79
isClarityType,
810
} from './clarityValue';
9-
import { ClarityType } from './constants';
10-
import { BooleanCV, TrueCV, FalseCV, trueCV, falseCV, boolCV } from './types/booleanCV';
11-
import { IntCV, UIntCV, intCV, uintCV } from './types/intCV';
12-
import { BufferCV, bufferCV, bufferCVFromString } from './types/bufferCV';
13-
import { OptionalCV, NoneCV, SomeCV, noneCV, someCV, optionalCVOf } from './types/optionalCV';
14-
15-
// todo: reduce manual re-exporting
11+
export * from './constants';
12+
export { BooleanCV, TrueCV, FalseCV, trueCV, falseCV, boolCV } from './types/booleanCV';
13+
export { IntCV, UIntCV, intCV, uintCV } from './types/intCV';
14+
export { BufferCV, bufferCV, bufferCVFromString } from './types/bufferCV';
15+
export { OptionalCV, NoneCV, SomeCV, noneCV, someCV, optionalCVOf } from './types/optionalCV';
1616

17-
import {
17+
export {
1818
ResponseCV,
1919
ResponseOkCV,
2020
ResponseErrorCV,
2121
responseOkCV,
2222
responseErrorCV,
2323
} from './types/responseCV';
2424

25-
import {
25+
export {
2626
StandardPrincipalCV,
2727
ContractPrincipalCV,
2828
standardPrincipalCV,
@@ -35,74 +35,14 @@ import {
3535
principalToString,
3636
} from './types/principalCV';
3737

38-
import { ListCV, listCV } from './types/listCV';
39-
import { TupleCV, tupleCV } from './types/tupleCV';
40-
import {
38+
export { ListCV, listCV } from './types/listCV';
39+
export { TupleCV, tupleCV } from './types/tupleCV';
40+
export {
4141
StringAsciiCV,
4242
StringUtf8CV,
4343
stringUtf8CV,
4444
stringAsciiCV,
4545
stringCV,
4646
} from './types/stringCV';
47-
import { serializeCV } from './serialize';
48-
import deserializeCV from './deserialize';
49-
50-
// Types
51-
export {
52-
ClarityType,
53-
ClarityValue,
54-
BooleanCV,
55-
TrueCV,
56-
FalseCV,
57-
IntCV,
58-
UIntCV,
59-
BufferCV,
60-
OptionalCV,
61-
NoneCV,
62-
SomeCV,
63-
ResponseCV,
64-
ResponseOkCV,
65-
ResponseErrorCV,
66-
PrincipalCV,
67-
StandardPrincipalCV,
68-
ContractPrincipalCV,
69-
ListCV,
70-
TupleCV,
71-
StringAsciiCV,
72-
StringUtf8CV,
73-
};
74-
75-
// Value construction functions
76-
export {
77-
boolCV,
78-
trueCV,
79-
falseCV,
80-
intCV,
81-
uintCV,
82-
bufferCV,
83-
bufferCVFromString,
84-
noneCV,
85-
someCV,
86-
optionalCVOf,
87-
responseOkCV,
88-
responseErrorCV,
89-
principalCV,
90-
standardPrincipalCV,
91-
standardPrincipalCVFromAddress,
92-
contractPrincipalCV,
93-
contractPrincipalCVFromAddress,
94-
contractPrincipalCVFromStandard,
95-
listCV,
96-
tupleCV,
97-
stringCV,
98-
stringAsciiCV,
99-
stringUtf8CV,
100-
getCVTypeString,
101-
isClarityType,
102-
};
103-
104-
// Serialization
105-
export { serializeCV, deserializeCV };
106-
107-
// toString
108-
export { cvToString, cvToJSON, cvToValue, principalToString };
47+
export { serializeCV } from './serialize';
48+
export { deserializeCV } from './deserialize';

packages/transactions/src/clarity/serialize.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ import {
2222
TupleCV,
2323
ClarityValue,
2424
} from '.';
25-
import { ClarityType } from './constants';
25+
import { ClarityType, clarityTypeToByte } from './constants';
2626

2727
import { SerializationError } from '../errors';
2828
import { StringAsciiCV, StringUtf8CV } from './types/stringCV';
2929
import { CLARITY_INT_BYTE_SIZE, CLARITY_INT_SIZE } from '../constants';
3030

3131
function bytesWithTypeID(typeId: ClarityType, bytes: Uint8Array): Uint8Array {
32-
return concatArray([typeId, bytes]);
32+
return concatArray([clarityTypeToByte(typeId), bytes]);
3333
}
3434

3535
function serializeBoolCV(value: BooleanCV): Uint8Array {
36-
return new Uint8Array([value.type]);
36+
return new Uint8Array([clarityTypeToByte(value.type)]);
3737
}
3838

3939
function serializeOptionalCV(cv: OptionalCV): Uint8Array {
4040
if (cv.type === ClarityType.OptionalNone) {
41-
return new Uint8Array([cv.type]);
41+
return new Uint8Array([clarityTypeToByte(cv.type)]);
4242
} else {
4343
return bytesWithTypeID(cv.type, serializeCV(cv.value));
4444
}

packages/transactions/src/clarity/types/booleanCV.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface FalseCV {
2020
* import { trueCV } from '@stacks/transactions';
2121
*
2222
* const trueCV = trueCV();
23-
* // { type: 3 }
23+
* // { type: 'true' }
2424
* ```
2525
*
2626
* @see
@@ -38,7 +38,7 @@ const trueCV = (): BooleanCV => ({ type: ClarityType.BoolTrue });
3838
* import { falseCV } from '@stacks/transactions';
3939
*
4040
* const falseCV = falseCV();
41-
* // { type: 4 }
41+
* // { type: 'false' }
4242
* ```
4343
*
4444
* @see
@@ -56,7 +56,7 @@ const falseCV = (): BooleanCV => ({ type: ClarityType.BoolFalse });
5656
* import { boolCV } from '@stacks/transactions';
5757
*
5858
* const boolCV = boolCV(false);
59-
* // { type: 4 }
59+
* // { type: 'false' }
6060
* ```
6161
*
6262
* @see

packages/transactions/src/clarity/types/bufferCV.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface BufferCV {
1919
*
2020
* const buffer = utf8ToBytes('this is a test');
2121
* const buf = bufferCV(buffer);
22-
* // { type: 2, buffer: <Uint8Array 74 68 69 73 20 69 73 20 61 20 74 65 73 74> }
22+
* // { type: 'buffer', buffer: <Uint8Array 74 68 69 73 20 69 73 20 61 20 74 65 73 74> }
2323
* const value = bytesToUtf8(buf.buffer);
2424
* // this is a test
2525
* ```
@@ -48,7 +48,7 @@ const bufferCV = (buffer: Uint8Array): BufferCV => {
4848
*
4949
* const str = 'this is a test';
5050
* const buf = bufferCVFromString(str);
51-
* // { type: 2, buffer: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74> }
51+
* // { type: 'buffer', buffer: <Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74> }
5252
* const value = bytesToUtf8(buf.buffer);
5353
* // this is a test
5454
*```

packages/transactions/src/clarity/types/intCV.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface IntCV {
2424
* import { intCV } from '@stacks/transactions';
2525
*
2626
* const value = intCV('100'); // parameter any of type: number | string | bigint | Uint8Array | BN
27-
* // { type: 0, value: 100n }
27+
* // { type: 'int', value: 100n }
2828
* ```
2929
*
3030
* @see
@@ -57,7 +57,7 @@ interface UIntCV {
5757
* import { uintCV } from '@stacks/transactions';
5858
*
5959
* const value = uintCV('100'); // parameter any of type: number | string | bigint | Uint8Array | BN
60-
* // { type: 1, value: 100n }
60+
* // { type: 'uint', value: 100n }
6161
* ```
6262
*
6363
* @see

packages/transactions/src/clarity/types/listCV.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface ListCV<T extends ClarityValue = ClarityValue> {
1818
* import { listCV, intCV } from '@stacks/transactions';
1919
*
2020
* const list = listCV([intCV(1), intCV(2), intCV(3), intCV(-4)]);
21-
* // { type: 11, list: [ { type: 0, value: 1n }, { type: 0, value: 2n }, { type: 0, value: 3n }, { type: 0, value: -4n } ] }
21+
* // { type: 'list', list: [ { type: 0, value: 1n }, { type: 0, value: 2n }, { type: 0, value: 3n }, { type: 0, value: -4n } ] }
2222
* ```
2323
*
2424
* @see

0 commit comments

Comments
 (0)