postchain-client
Version:
Client library for accessing a Postchain node through REST.
129 lines • 4.2 kB
JavaScript
import { Buffer } from "buffer";
import { rawGTV } from "../gtv/definition";
import { BN } from "bn.js";
import { UnexpectedArgumentTypeError } from "./errors";
import { checkGtxType } from "../formatter";
export function encodeValue(rawGtv) {
return rawGTV.encode(createTypedArg(rawGtv));
}
export function encodeValueGtx(rawGtx) {
return encodeValue(rawGtx);
}
export function decodeValue(bytes) {
//TODO add a try catch to catch asn1 errors to be more readable error
const obj = rawGTV.decode(bytes);
return parseValue(obj);
}
export function decodeValueGtx(bytes) {
const decodedValue = decodeValue(bytes);
if (!checkGtxType(decodedValue)) {
throw new Error(`Unexpected type of value: ${decodedValue}, expected decoded value to be of type RawGtx`);
}
return decodedValue;
}
export function parseValue(typedArg) {
var _a, _b;
if (typedArg.type === "null") {
return null;
}
else if (typedArg.type === "byteArray") {
return typedArg.value;
}
else if (typedArg.type === "string") {
return typedArg.value;
}
else if (typedArg.type === "integer") {
return Number(typedArg.value);
}
else if (typedArg.type === "array") {
const arrayValue = typedArg.value;
return arrayValue.map((item) => parseValue(item));
}
else if (typedArg.type === "bigInteger") {
return BigInt((_b = (_a = typedArg.value) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "");
}
else if (typedArg.type === "dict") {
const arrayValue = typedArg.value;
const result = {};
arrayValue.forEach((pair) => {
result[pair.name] = parseValue(pair.value);
});
return result;
}
else {
throw new UnexpectedArgumentTypeError(typedArg);
}
}
export function createTypedArg(value) {
try {
if (value == null) {
return { type: "null", value: null };
}
if (Buffer.isBuffer(value)) {
return { type: "byteArray", value: value };
}
if (typeof value === "boolean") {
return { type: "integer", value: value ? 1 : 0 };
}
if (typeof value === "string") {
return { type: "string", value: value };
}
if (typeof value === "number") {
if (!Number.isInteger(value)) {
throw Error("User error: Only integers are supported");
}
return { type: "integer", value: new BN(value) };
}
if (typeof value === "bigint") {
return { type: "bigInteger", value: new BN(value.toString()) };
}
if (value.constructor === Array) {
return {
type: "array",
value: value.map((item) => createTypedArg(item)),
};
}
if (typeof value === "object") {
let valueAsDictPair = value;
if (isDictPairWithStringKey(valueAsDictPair)) {
valueAsDictPair = sortDictPairByKey(valueAsDictPair);
}
return {
type: "dict",
value: Object.keys(valueAsDictPair).map(function (key) {
return { name: key, value: createTypedArg(valueAsDictPair[key]) };
}),
};
}
}
catch (error) {
const message = value ? value.toString() : "RawGtv";
throw new Error(`Failed to encode ${message}: ${error}`);
}
throw new Error(`value ${value} have unsupported type: ${typeof value}`);
}
function isDictPairWithStringKey(obj) {
for (const key in obj) {
if (typeof key !== "string") {
return false;
}
}
return true;
}
function sortDictPairByKey(dict) {
const sortedArray = Object.entries(dict).sort(([keyA], [keyB]) => {
if (keyA < keyB) {
return -1;
}
if (keyA > keyB) {
return 1;
}
return 0;
});
const sortedDict = {};
for (const [key, value] of sortedArray) {
sortedDict[key] = value;
}
return sortedDict;
}
//# sourceMappingURL=serialization.js.map