@unruggable/gateways
Version:
Trustless Ethereum Multichain CCIP-Read Gateway
118 lines (117 loc) • 4.14 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProgramReader = void 0;
const utils_1 = require("ethers/utils");
const vm_js_1 = require("./vm.cjs");
const ops_js_1 = require("./ops.cjs");
const NAMES = [];
Object.entries(ops_js_1.GATEWAY_OP).forEach(([name, op]) => (NAMES[op] = name));
class ProgramReader {
ops;
static actions(program) {
const reader = this.fromProgram(program);
const actions = [];
if (program instanceof vm_js_1.GatewayRequest) {
actions.push({
pos: 0,
op: reader.readByte(), // outputCount,
name: 'OUTPUT_COUNT',
});
}
while (reader.remaining) {
actions.push(reader.readAction());
}
return actions;
}
static fromProgram(program) {
return new this(Uint8Array.from(program.ops));
}
static fromBytes(v) {
return new this((0, utils_1.getBytes)(v));
}
pos = 0;
constructor(ops) {
this.ops = ops;
}
get remaining() {
return this.ops.length - this.pos;
}
checkRead(n) {
if (this.pos + n > this.ops.length)
throw new Error('reader overflow');
}
readByte() {
this.checkRead(1);
return this.ops[this.pos++];
}
readBytes(n) {
this.checkRead(n);
return (0, utils_1.hexlify)(this.ops.subarray(this.pos, (this.pos += n)));
}
readUint() {
const n = this.readByte();
if (n > 32)
throw new Error(`expected word size: ${n}`);
return n ? BigInt(this.readBytes(n)) : 0n;
}
readSmallStr() {
return (0, utils_1.toUtf8String)(this.readBytes(this.readByte()));
}
parseArgs(op) {
// TODO: this is probably incomplete
switch (op) {
//case OP.PUSH_0:
case ops_js_1.GATEWAY_OP.PUSH_1:
case ops_js_1.GATEWAY_OP.PUSH_2:
case ops_js_1.GATEWAY_OP.PUSH_3:
case ops_js_1.GATEWAY_OP.PUSH_4:
case ops_js_1.GATEWAY_OP.PUSH_5:
case ops_js_1.GATEWAY_OP.PUSH_6:
case ops_js_1.GATEWAY_OP.PUSH_7:
case ops_js_1.GATEWAY_OP.PUSH_8:
case ops_js_1.GATEWAY_OP.PUSH_9:
case ops_js_1.GATEWAY_OP.PUSH_10:
case ops_js_1.GATEWAY_OP.PUSH_11:
case ops_js_1.GATEWAY_OP.PUSH_12:
case ops_js_1.GATEWAY_OP.PUSH_13:
case ops_js_1.GATEWAY_OP.PUSH_14:
case ops_js_1.GATEWAY_OP.PUSH_15:
case ops_js_1.GATEWAY_OP.PUSH_16:
case ops_js_1.GATEWAY_OP.PUSH_17:
case ops_js_1.GATEWAY_OP.PUSH_18:
case ops_js_1.GATEWAY_OP.PUSH_19:
case ops_js_1.GATEWAY_OP.PUSH_20:
case ops_js_1.GATEWAY_OP.PUSH_21:
case ops_js_1.GATEWAY_OP.PUSH_22:
case ops_js_1.GATEWAY_OP.PUSH_23:
case ops_js_1.GATEWAY_OP.PUSH_24:
case ops_js_1.GATEWAY_OP.PUSH_25:
case ops_js_1.GATEWAY_OP.PUSH_26:
case ops_js_1.GATEWAY_OP.PUSH_27:
case ops_js_1.GATEWAY_OP.PUSH_28:
case ops_js_1.GATEWAY_OP.PUSH_29:
case ops_js_1.GATEWAY_OP.PUSH_30:
case ops_js_1.GATEWAY_OP.PUSH_31:
case ops_js_1.GATEWAY_OP.PUSH_32:
return { bytes: this.readBytes(op) };
case ops_js_1.GATEWAY_OP.PUSH_BYTES:
return { bytes: this.readBytes(Number(this.readUint())) };
case ops_js_1.GATEWAY_OP.EVAL_LOOP:
return { flags: this.readByte() };
case ops_js_1.GATEWAY_OP.ASSERT:
return { exitCode: this.readByte() };
case ops_js_1.GATEWAY_OP.DEBUG:
return { label: this.readSmallStr() };
default:
return {};
}
}
readAction() {
const op = this.readByte();
const name = NAMES[op];
if (!name)
throw new Error(`unknown op: ${op}`);
return { pos: this.pos, op, name, ...this.parseArgs(op) };
}
}
exports.ProgramReader = ProgramReader;