Skip to content

Commit d6b9526

Browse files
Volodymyr-KuchinskyiVladimir Kuchinskiy
and
Vladimir Kuchinskiy
authored
Fixed parsing ByteArray for schema (#12)
Co-authored-by: Vladimir Kuchinskiy <[email protected]>
1 parent ecd5217 commit d6b9526

File tree

5 files changed

+217
-11
lines changed

5 files changed

+217
-11
lines changed

package-lock.json

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
}
3737
},
3838
"dependencies": {
39-
"casper-js-sdk": "^2.11.0"
39+
"casper-js-sdk": "^2.11.0",
40+
"ts-results": "^3.3.0"
4041
},
4142
"devDependencies": {
4243
"@types/jest": "^29.4.0",

src/casper/utils.ts

Lines changed: 183 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
1-
import { matchBytesToCLType } from 'casper-js-sdk';
1+
import {
2+
CLBoolType,
3+
CLByteArrayType,
4+
CLI32Type,
5+
CLI64Type,
6+
CLKeyType,
7+
CLListType,
8+
CLMapType,
9+
CLOptionType,
10+
CLPublicKeyType,
11+
CLResultType,
12+
CLStringType,
13+
CLTuple1Type,
14+
CLType,
15+
CLTypeTag,
16+
CLU128Type,
17+
CLU256Type,
18+
CLU32BytesParser,
19+
CLU32Type,
20+
CLU512Type,
21+
CLU64Type,
22+
CLU8Type,
23+
CLUnitType,
24+
CLURefType,
25+
ResultAndRemainder,
26+
resultHelper,
27+
} from 'casper-js-sdk';
28+
import { Err, Ok } from 'ts-results';
229
import { RawCLValue, WithRemainder } from './types';
330

431
export function parseBytesWithRemainder(
@@ -43,3 +70,158 @@ export function parseCLValueFromBytesWithRemainder(
4370
remainder: clTypeWithRemainder.remainder,
4471
};
4572
}
73+
74+
export function matchBytesToCLType(
75+
bytes: Uint8Array,
76+
): ResultAndRemainder<CLType, string> {
77+
const tag = bytes[0];
78+
const remainder = bytes.subarray(1);
79+
80+
switch (tag) {
81+
case CLTypeTag.Bool:
82+
return resultHelper(Ok(new CLBoolType()), remainder);
83+
case CLTypeTag.I32:
84+
return resultHelper(Ok(new CLI32Type()), remainder);
85+
case CLTypeTag.I64:
86+
return resultHelper(Ok(new CLI64Type()), remainder);
87+
case CLTypeTag.U8:
88+
return resultHelper(Ok(new CLU8Type()), remainder);
89+
case CLTypeTag.U32:
90+
return resultHelper(Ok(new CLU32Type()), remainder);
91+
case CLTypeTag.U64:
92+
return resultHelper(Ok(new CLU64Type()), remainder);
93+
case CLTypeTag.U64:
94+
return resultHelper(Ok(new CLU64Type()), remainder);
95+
case CLTypeTag.U128:
96+
return resultHelper(Ok(new CLU128Type()), remainder);
97+
case CLTypeTag.U256:
98+
return resultHelper(Ok(new CLU256Type()), remainder);
99+
case CLTypeTag.U512:
100+
return resultHelper(Ok(new CLU512Type()), remainder);
101+
case CLTypeTag.Unit:
102+
return resultHelper(Ok(new CLUnitType()), remainder);
103+
case CLTypeTag.String:
104+
return resultHelper(Ok(new CLStringType()), remainder);
105+
case CLTypeTag.Key:
106+
return resultHelper(Ok(new CLKeyType()), remainder);
107+
case CLTypeTag.URef:
108+
return resultHelper(Ok(new CLURefType()), remainder);
109+
case CLTypeTag.Option: {
110+
const { result, remainder: typeRem } = matchBytesToCLType(remainder);
111+
112+
const innerType = result.unwrap();
113+
114+
return resultHelper(Ok(new CLOptionType(innerType)), typeRem);
115+
}
116+
case CLTypeTag.List: {
117+
const { result, remainder: typeRem } = matchBytesToCLType(remainder);
118+
119+
const innerType = result.unwrap();
120+
121+
return resultHelper(Ok(new CLListType(innerType)), typeRem);
122+
}
123+
case CLTypeTag.ByteArray: {
124+
const { result: sizeRes, remainder: rem } =
125+
new CLU32BytesParser().fromBytesWithRemainder(remainder);
126+
127+
const size = sizeRes.unwrap().value().toNumber();
128+
129+
return resultHelper(Ok(new CLByteArrayType(size)), rem);
130+
}
131+
case CLTypeTag.Result: {
132+
const { result: okTypeRes, remainder: okTypeRem } =
133+
matchBytesToCLType(remainder);
134+
const okType = okTypeRes.unwrap();
135+
136+
if (!okTypeRem)
137+
return resultHelper(Err('Missing Error type bytes in Result'));
138+
139+
const { result: errTypeRes, remainder: rem } =
140+
matchBytesToCLType(okTypeRem);
141+
const errType = errTypeRes.unwrap();
142+
143+
return resultHelper(
144+
Ok(new CLResultType({ ok: okType, err: errType })),
145+
rem,
146+
);
147+
}
148+
case CLTypeTag.Map: {
149+
const { result: keyTypeRes, remainder: keyTypeRem } =
150+
matchBytesToCLType(remainder);
151+
const keyType = keyTypeRes.unwrap();
152+
153+
if (!keyTypeRem)
154+
return resultHelper(Err('Missing Key type bytes in Map'));
155+
156+
const { result: valTypeRes, remainder: rem } =
157+
matchBytesToCLType(keyTypeRem);
158+
const valType = valTypeRes.unwrap();
159+
160+
return resultHelper(Ok(new CLMapType([keyType, valType])), rem);
161+
}
162+
case CLTypeTag.Tuple1: {
163+
const { result: innerTypeRes, remainder: rem } =
164+
matchBytesToCLType(remainder);
165+
const innerType = innerTypeRes.unwrap();
166+
167+
return resultHelper(Ok(new CLTuple1Type([innerType])), rem);
168+
}
169+
case CLTypeTag.Tuple2: {
170+
const { result: innerType1Res, remainder: innerType1Rem } =
171+
matchBytesToCLType(remainder);
172+
const innerType1 = innerType1Res.unwrap();
173+
174+
if (!innerType1Rem) {
175+
return resultHelper(
176+
Err('Missing second tuple type bytes in CLTuple2Type'),
177+
);
178+
}
179+
180+
const { result: innerType2Res, remainder: innerType2Rem } =
181+
matchBytesToCLType(innerType1Rem);
182+
const innerType2 = innerType2Res.unwrap();
183+
184+
return resultHelper(
185+
Ok(new CLTuple1Type([innerType1, innerType2])),
186+
innerType2Rem,
187+
);
188+
}
189+
case CLTypeTag.Tuple3: {
190+
const { result: innerType1Res, remainder: innerType1Rem } =
191+
matchBytesToCLType(remainder);
192+
const innerType1 = innerType1Res.unwrap();
193+
194+
if (!innerType1Rem) {
195+
return resultHelper(
196+
Err('Missing second tuple type bytes in CLTuple2Type'),
197+
);
198+
}
199+
200+
const { result: innerType2Res, remainder: innerType2Rem } =
201+
matchBytesToCLType(innerType1Rem);
202+
const innerType2 = innerType2Res.unwrap();
203+
204+
if (!innerType2Rem) {
205+
return resultHelper(
206+
Err('Missing third tuple type bytes in CLTuple2Type'),
207+
);
208+
}
209+
210+
const { result: innerType3Res, remainder: innerType3Rem } =
211+
matchBytesToCLType(innerType2Rem);
212+
const innerType3 = innerType3Res.unwrap();
213+
214+
return resultHelper(
215+
Ok(new CLTuple1Type([innerType1, innerType2, innerType3])),
216+
innerType3Rem,
217+
);
218+
}
219+
case CLTypeTag.Any: {
220+
return resultHelper(Err('Any unsupported'));
221+
}
222+
case CLTypeTag.PublicKey:
223+
return resultHelper(Ok(new CLPublicKeyType()), remainder);
224+
}
225+
226+
return resultHelper(Err('Unsuported type'));
227+
}

src/schema.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
import {
2-
CasperServiceByJsonRPC,
3-
CLType,
4-
decodeBase16,
5-
matchBytesToCLType,
6-
} from 'casper-js-sdk';
1+
import { CasperServiceByJsonRPC, CLType, decodeBase16 } from 'casper-js-sdk';
72
import { WithRemainder } from './casper/types';
8-
import { parseBytesWithRemainder } from './casper/utils';
3+
import { matchBytesToCLType, parseBytesWithRemainder } from './casper/utils';
94
import { EVENTS_SCHEMA_NAMED_KEY } from './parser';
105

116
export type Schemas = Record<string, Schema>;

test/schema.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe('Schema', () => {
2222
expect(schema.data[1].value.tag).toEqual(CLTypeTag.Key);
2323
});
2424

25-
it('should parse schema from raw bytes with option conmplex type', () => {
25+
it('should parse schema from raw bytes with option complex type', () => {
2626
const hexStr = '01000000060000006f7074696f6e0d0b';
2727
const schema = parseSchemaFromBytesWithRemainder(decodeBase16(hexStr));
2828

@@ -47,5 +47,22 @@ describe('Schema', () => {
4747
CLTypeTag.Key,
4848
);
4949
});
50+
51+
it('should parse schema from raw bytes with byte array type', () => {
52+
const hexStr =
53+
'030000000a000000636f6c6c656374696f6e0f2000000008000000746f6b656e5f696407070000006f6666657265720b';
54+
const schema = parseSchemaFromBytesWithRemainder(decodeBase16(hexStr));
55+
56+
expect(schema.data.length).toEqual(3);
57+
58+
expect(schema.data[0].property).toEqual('collection');
59+
expect(schema.data[0].value.tag).toEqual(CLTypeTag.ByteArray);
60+
61+
expect(schema.data[1].property).toEqual('token_id');
62+
expect(schema.data[1].value.tag).toEqual(CLTypeTag.U256);
63+
64+
expect(schema.data[2].property).toEqual('offerer');
65+
expect(schema.data[2].value.tag).toEqual(CLTypeTag.Key);
66+
});
5067
});
5168
});

0 commit comments

Comments
 (0)