heimdall-tide
Version:
SDK for communicating with a Tide Enclave
133 lines • 5.16 kB
JavaScript
import { TideMemory } from "asgard-tide";
export const version = "1";
export function wrapper(arr) {
// If array is only Uint8Arrays - create a TideMemory out of it
// If there is any entry in an array that is another array
// -> Go inside that array and repeat the process
if (arr.every(a => a instanceof Uint8Array))
return TideMemory.CreateFromArray(arr);
else {
// Go through each entry
arr.forEach((a) => {
// If the entry is an array, apply the wappa on it
if (Array.isArray(a)) {
// Reassign the value of the entry -> to the serialized wrapper
a = wrapper(a);
}
else if (a["value"]) {
// Let's check if is a number, boolean or Uint8Array. If none of those, it'll be null
const res = encode(a["value"]);
if (res) {
// serialized correctly
a = res;
}
else {
if (typeof a["value"] == "string") {
// Serialize it into Uint8Array
if (!a["encoding"]) {
// No encoding provided
// Let's default to UTF-8
a = encodeStr(a["value"], "UTF-8");
}
else {
a = encodeStr(a["value"], a["encoding"]);
}
}
else
throw 'Unsupported type';
}
}
else
throw 'Unexpected format';
});
if (arr.every(a => a instanceof Uint8Array))
return TideMemory.CreateFromArray(arr); // Check to make sure everything was serialized correctly from the wappa
else
throw 'There was an error encoding all your values';
}
}
export function encodeStr(str, enc) {
switch (enc) {
case "UTF-8":
return new TextEncoder().encode(str);
case "HEX":
// 1) Strip 0x prefix
let normalized = str.replace(/^0x/i, "");
// treat empty as invalid
if (normalized.length === 0) {
throw new Error("Empty hex string");
}
// 2) Pad odd length
if (normalized.length % 2 !== 0) {
normalized = "0" + normalized;
}
// 3) Validate
if (!/^[0-9A-Fa-f]+$/.test(normalized)) {
throw new Error("Invalid hex string");
}
// 4) Parse into bytes
const byteCount = normalized.length / 2;
const out = new Uint8Array(byteCount);
for (let i = 0; i < byteCount; i++) {
out[i] = Number.parseInt(normalized.slice(i * 2, i * 2 + 2), 16);
}
return out;
case "B64":
const binaryString = atob(str);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
case "B64URL":
// 1) Replace URL-safe chars with standard Base64 chars
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
// 2) Pad with '=' so length is a multiple of 4
const pad = base64.length % 4;
if (pad === 2) {
base64 += '==';
}
else if (pad === 3) {
base64 += '=';
}
else if (pad === 1) {
// This shouldn’t happen for valid Base64-URL, but just in case…
base64 += '===';
}
// 3) Decode to binary string
const binary = atob(base64);
// 4) Convert to Uint8Array
const ulen = binary.length;
const ubytes = new Uint8Array(ulen);
for (let i = 0; i < ulen; i++) {
ubytes[i] = binary.charCodeAt(i);
}
return ubytes;
default:
// catches anything else (should never happen)
throw new TypeError(`Unsupported encoding: ${enc}`);
}
}
export function encode(data) {
switch (typeof data) {
case 'number':
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, data, true);
return new Uint8Array(buffer);
case 'boolean':
return new Uint8Array([data ? 1 : 0]);
case 'object':
// since a Uint8Array is an object at runtime, we need to check it here
if (data instanceof Uint8Array) {
return new Uint8Array(data.slice(0));
}
// if we fall through, it wasn't one of our allowed types
throw new TypeError(`Unsupported object type: ${data}`);
default:
// catches anything else (should never happen)
return undefined;
}
}
//# sourceMappingURL=wrapper.js.map