UNPKG

@unruggable/gateways

Version:

Trustless Ethereum Multichain CCIP-Read Gateway

118 lines (117 loc) 4.14 kB
"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;