UNPKG

@mavrykdynamics/taquito-local-forging

Version:

Provide local forging functionality to be with taquito

1,492 lines (1,483 loc) 57.8 kB
import { Prefix, buf2hex, b58cdecode, prefix, prefixLength, b58cencode, InvalidKeyHashError, invalidDetail, ValidationResult, InvalidPublicKeyError, validateBlock } from '@mavrykdynamics/taquito-utils'; import { ParameterValidationError, InvalidHexStringError, InvalidAddressError, InvalidContractAddressError, InvalidOperationKindError, InvalidBlockHashError } from '@mavrykdynamics/taquito-core'; import BigNumber$1, { BigNumber } from 'bignumber.js'; const toHexString = (bytes) => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), ''); const pad = (num, paddingLen = 8) => { return num.toString(16).padStart(paddingLen, '0'); }; /* * Some code in this file is originally from sotez * Copyright (c) 2018 Andrew Kishino */ // See: https://protocol.mavryk.org/protocols/005_babylon.html#transactions-now-have-an-entrypoint const ENTRYPOINT_MAX_LENGTH = 31; var CODEC; (function (CODEC) { CODEC["SECRET"] = "secret"; CODEC["RAW"] = "raw"; CODEC["MV1"] = "mv1"; CODEC["BRANCH"] = "branch"; CODEC["ZARITH"] = "zarith"; CODEC["PUBLIC_KEY"] = "public_key"; CODEC["PKH"] = "pkh"; CODEC["PKH_ARR"] = "pkhArr"; CODEC["DELEGATE"] = "delegate"; CODEC["SCRIPT"] = "script"; CODEC["BALLOT_STATEMENT"] = "ballotStmt"; CODEC["PROPOSAL"] = "proposal"; CODEC["PROPOSAL_ARR"] = "proposalArr"; CODEC["INT32"] = "int32"; CODEC["INT16"] = "int16"; CODEC["PARAMETERS"] = "parameters"; CODEC["ADDRESS"] = "address"; CODEC["SMART_CONTRACT_ADDRESS"] = "smart_contract_address"; CODEC["SMART_ROLLUP_ADDRESS"] = "smart_rollup_address"; CODEC["SMART_ROLLUP_COMMITMENT_HASH"] = "smart_rollup_commitment_hash"; CODEC["VALUE"] = "value"; CODEC["PADDED_BYTES"] = "padded_bytes"; CODEC["SMART_ROLLUP_MESSAGE"] = "smart_rollup_message"; CODEC["MANAGER"] = "manager"; CODEC["BLOCK_PAYLOAD_HASH"] = "blockPayloadHash"; CODEC["ENTRYPOINT"] = "entrypoint"; CODEC["OPERATION"] = "operation"; CODEC["OP_ACTIVATE_ACCOUNT"] = "activate_account"; CODEC["OP_DELEGATION"] = "delegation"; CODEC["OP_TRANSACTION"] = "transaction"; CODEC["OP_ORIGINATION"] = "origination"; CODEC["OP_BALLOT"] = "ballot"; CODEC["OP_FAILING_NOOP"] = "failing_noop"; CODEC["OP_ATTESTATION"] = "attestation"; CODEC["OP_ATTESTATION_WITH_DAL"] = "attestation_with_dal"; CODEC["OP_SEED_NONCE_REVELATION"] = "seed_nonce_revelation"; CODEC["OP_REVEAL"] = "reveal"; CODEC["OP_PROPOSALS"] = "proposals"; CODEC["OP_REGISTER_GLOBAL_CONSTANT"] = "register_global_constant"; CODEC["OP_TRANSFER_TICKET"] = "transfer_ticket"; CODEC["BURN_LIMIT"] = "burn_limit"; CODEC["OP_INCREASE_PAID_STORAGE"] = "increase_paid_storage"; CODEC["OP_UPDATE_CONSENSUS_KEY"] = "update_consensus_key"; CODEC["OP_DRAIN_DELEGATE"] = "drain_delegate"; CODEC["DEPOSITS_LIMIT"] = "deposits_limit"; CODEC["OP_SET_DEPOSITS_LIMIT"] = "set_deposits_limit"; CODEC["OP_SMART_ROLLUP_ORIGINATE"] = "smart_rollup_originate"; CODEC["PVM_KIND"] = "pvm_kind"; CODEC["OP_SMART_ROLLUP_ADD_MESSAGES"] = "smart_rollup_add_messages"; CODEC["OP_SMART_ROLLUP_EXECUTE_OUTBOX_MESSAGE"] = "smart_rollup_execute_outbox_message"; CODEC["OP_DAL_PUBLISH_COMMITMENT"] = "dal_publish_commitment"; CODEC["SLOT_HEADER"] = "slot_header"; })(CODEC || (CODEC = {})); // See https://protocol.mavryk.org/shell/p2p_api.html#alpha-michelson-v1-primitives-enumeration-unsigned-8-bit-integer const opMapping = { '00': 'parameter', '01': 'storage', '02': 'code', '03': 'False', '04': 'Elt', '05': 'Left', '06': 'None', '07': 'Pair', '08': 'Right', '09': 'Some', '0a': 'True', '0b': 'Unit', '0c': 'PACK', '0d': 'UNPACK', '0e': 'BLAKE2B', '0f': 'SHA256', '10': 'SHA512', '11': 'ABS', '12': 'ADD', '13': 'AMOUNT', '14': 'AND', '15': 'BALANCE', '16': 'CAR', '17': 'CDR', '18': 'CHECK_SIGNATURE', '19': 'COMPARE', '1a': 'CONCAT', '1b': 'CONS', '1c': 'CREATE_ACCOUNT', '1d': 'CREATE_CONTRACT', '1e': 'IMPLICIT_ACCOUNT', '1f': 'DIP', '20': 'DROP', '21': 'DUP', '22': 'EDIV', '23': 'EMPTY_MAP', '24': 'EMPTY_SET', '25': 'EQ', '26': 'EXEC', '27': 'FAILWITH', '28': 'GE', '29': 'GET', '2a': 'GT', '2b': 'HASH_KEY', '2c': 'IF', '2d': 'IF_CONS', '2e': 'IF_LEFT', '2f': 'IF_NONE', '30': 'INT', '31': 'LAMBDA', '32': 'LE', '33': 'LEFT', '34': 'LOOP', '35': 'LSL', '36': 'LSR', '37': 'LT', '38': 'MAP', '39': 'MEM', '3a': 'MUL', '3b': 'NEG', '3c': 'NEQ', '3d': 'NIL', '3e': 'NONE', '3f': 'NOT', '40': 'NOW', '41': 'OR', '42': 'PAIR', '43': 'PUSH', '44': 'RIGHT', '45': 'SIZE', '46': 'SOME', '47': 'SOURCE', '48': 'SENDER', '49': 'SELF', '4a': 'STEPS_TO_QUOTA', '4b': 'SUB', '4c': 'SWAP', '4d': 'TRANSFER_TOKENS', '4e': 'SET_DELEGATE', '4f': 'UNIT', '50': 'UPDATE', '51': 'XOR', '52': 'ITER', '53': 'LOOP_LEFT', '54': 'ADDRESS', '55': 'CONTRACT', '56': 'ISNAT', '57': 'CAST', '58': 'RENAME', '59': 'bool', '5a': 'contract', '5b': 'int', '5c': 'key', '5d': 'key_hash', '5e': 'lambda', '5f': 'list', '60': 'map', '61': 'big_map', '62': 'nat', '63': 'option', '64': 'or', '65': 'pair', '66': 'set', '67': 'signature', '68': 'string', '69': 'bytes', '6a': 'mumav', '6b': 'timestamp', '6c': 'unit', '6d': 'operation', '6e': 'address', '6f': 'SLICE', '70': 'DIG', '71': 'DUG', '72': 'EMPTY_BIG_MAP', '73': 'APPLY', '74': 'chain_id', '75': 'CHAIN_ID', '76': 'LEVEL', '77': 'SELF_ADDRESS', '78': 'never', '79': 'NEVER', '7a': 'UNPAIR', '7b': 'VOTING_POWER', '7c': 'TOTAL_VOTING_POWER', '7d': 'KECCAK', '7e': 'SHA3', '7f': 'PAIRING_CHECK', '80': 'bls12_381_g1', '81': 'bls12_381_g2', '82': 'bls12_381_fr', '83': 'sapling_state', '84': 'sapling_transaction_deprecated', '85': 'SAPLING_EMPTY_STATE', '86': 'SAPLING_VERIFY_UPDATE', '87': 'ticket', '88': 'TICKET_DEPRECATED', '89': 'READ_TICKET', '8a': 'SPLIT_TICKET', '8b': 'JOIN_TICKETS', '8c': 'GET_AND_UPDATE', '8d': 'chest', '8e': 'chest_key', '8f': 'OPEN_CHEST', '90': 'VIEW', '91': 'view', '92': 'constant', '93': 'SUB_MUMAV', '94': 'tx_rollup_l2_address', '95': 'MIN_BLOCK_TIME', '96': 'sapling_transaction', '97': 'EMIT', '98': 'Lambda_rec', '99': 'LAMBDA_REC', '9a': 'TICKET', '9b': 'BYTES', '9c': 'NAT', '9d': 'Ticket', }; const opMappingReverse = (() => { const result = {}; Object.keys(opMapping).forEach((key) => { result[opMapping[key]] = key; }); return result; })(); // See https://protocol.mavryk.org/shell/p2p_api.html const kindMapping = { 0x04: 'activate_account', 0x6b: 'reveal', 0x6e: 'delegation', 0x6c: 'transaction', 0x6d: 'origination', 0x06: 'ballot', 0x15: 'attestation', 0x17: 'attestation_with_dal', 0x01: 'seed_nonce_revelation', 0x05: 'proposals', 0x6f: 'register_global_constant', 0x9e: 'transfer_ticket', 0x70: 'set_deposits_limit', 0x71: 'increase_paid_storage', 0x72: 'update_consensus_key', 0x09: 'drain_delegate', 0xc8: 'smart_rollup_originate', 0xc9: 'smart_rollup_add_messages', 0xce: 'smart_rollup_execute_outbox_message', 0xe6: 'dal_publish_commitment', 0x11: 'failing_noop', }; const kindMappingReverse = (() => { const result = {}; Object.keys(kindMapping).forEach((key) => { const keyNum = typeof key === 'string' ? parseInt(key, 10) : key; result[kindMapping[keyNum]] = pad(keyNum, 2); }); return result; })(); // See https://protocol.mavryk.org/protocols/005_babylon.html#transactions-now-have-an-entrypoint const entrypointMapping = { '00': 'default', '01': 'root', '02': 'do', '03': 'set_delegate', '04': 'remove_delegate', '05': 'deposit', '06': 'stake', '07': 'unstake', '08': 'finalize_unstake', '09': 'set_delegate_parameters', }; const entrypointMappingReverse = (() => { const result = {}; Object.keys(entrypointMapping).forEach((key) => { result[entrypointMapping[key]] = key; }); return result; })(); /** * @category Error * @description Error that indicates an invalid operation content being passed or used */ class InvalidOperationSchemaError extends ParameterValidationError { constructor(operation, errorDetail) { super(); this.operation = operation; this.errorDetail = errorDetail; this.name = 'InvalidOperationSchemaError'; this.message = `Invalid operation content recevied`; errorDetail ? (this.message += ` ${errorDetail}.`) : ''; } } /** * @category Error * @description Error that indicates an entrypoint name exceeding maximum length */ class OversizedEntryPointError extends ParameterValidationError { constructor(entrypoint) { super(); this.entrypoint = entrypoint; this.name = 'OversizedEntryPointError'; this.message = `Invalid entrypoint length "${entrypoint.length}", maximum length is "${ENTRYPOINT_MAX_LENGTH}".`; } } /** * @category Error * @description Error that indicates an invalid ballot value being used */ class InvalidBallotValueError extends ParameterValidationError { constructor(ballotValue) { super(); this.ballotValue = ballotValue; this.name = 'InvalidBallotValueError'; this.message = `Invalid ballot value "${ballotValue}" expecting one of the following: "yay", "nay", "pass".`; } } /** * @category Error * @description Error that indicates a failure when trying to decode ballot value */ class DecodeBallotValueError extends ParameterValidationError { constructor(ballotValue) { super(); this.ballotValue = ballotValue; this.name = 'DecodeBallotValueError'; this.message = `Invalid ballot value "${ballotValue}", cannot be decoded.`; } } /** * @category Error * @description Error that indicates unexpected Michelson Value being passed or used */ class UnexpectedMichelsonValueError extends ParameterValidationError { constructor(value) { super(); this.value = value; this.name = 'UnexpectedMichelsonValueError'; this.message = `Invalid Michelson value "${value}", unalbe to encode.`; } } /** * @category Error * @description Error that indicates a failure when trying to decode an operation */ class OperationDecodingError extends ParameterValidationError { constructor(message) { super(); this.message = message; this.name = 'OperationDecodingError'; } } /** * @category Error * @description Error that indicates a failure when trying to encode an operation */ class OperationEncodingError extends ParameterValidationError { constructor(message) { super(); this.message = message; this.name = 'OperationEncodingError'; } } /** * @category Error * @description Error that indicates an unsupported operation being passed or used */ class UnsupportedOperationError extends ParameterValidationError { constructor(op) { super(); this.op = op; this.name = 'UnsupportedOperationError'; this.message = `Unsupported operation "${op}", can submit an issue on our github for feature request.`; } } /** * @cateogry Error * @description Error that indicates an unsupported pvm being passed or used */ class UnsupportedPvmKindError extends ParameterValidationError { constructor(pvm) { super(); this.pvm = pvm; this.name = 'UnsupportedPvmKindError'; this.message = `Invalid Pvm kind "${pvm}" expecting either "arith" or "wasm_2_0_0".`; } } /** * @category Error * @description Error that indicates an unsupported pvm to decode */ class DecodePvmKindError extends ParameterValidationError { constructor(pvm) { super(); this.pvm = pvm; this.name = 'DecodePvmKindError'; this.message = `Invalid Pvm kind "${pvm}", cannot be decoded.`; } } /** * @category Error * @description Error that indicates an invalid Smart Rollup Address (sr1) */ class InvalidSmartRollupAddressError extends ParameterValidationError { constructor(address, errorDetail) { super(); this.address = address; this.errorDetail = errorDetail; this.name = 'InvalidSmartRollupAddress'; this.message = `Invalid smart rollup address "${address}"`; errorDetail ? (this.message += ` ${errorDetail}.`) : ''; } } /** * @category Error * @description Error that indicates an invalid Smart Rollup commitment hash (src1) */ class InvalidSmartRollupCommitmentHashError extends ParameterValidationError { constructor(hash, errorDetail) { super(); this.hash = hash; this.errorDetail = errorDetail; this.name = 'InvalidSmartRollupCommitmentHashError'; this.message = `Invalid smart rollup commitment hash "${hash}"`; errorDetail ? (this.message += ` ${errorDetail}.`) : ''; } } /** * @category Error * @description Error that indicates an invalid dal commitment (sh) */ class InvalidDalCommitmentError extends ParameterValidationError { constructor(commitment, errorDetail) { super(); this.commitment = commitment; this.errorDetail = errorDetail; this.name = 'InvalidDalCommitmentError'; this.message = `Invalid dal commitment "${commitment}"`; errorDetail ? (this.message += ` ${errorDetail}.`) : ''; } } class Uint8ArrayConsumer { static fromHexString(hex) { const lowHex = hex.toLowerCase(); if (/^(([a-f]|\d){2})*$/.test(lowHex)) { const arr = new Uint8Array((lowHex.match(/([a-z]|\d){2}/g) || []).map((byte) => parseInt(byte, 16))); return new Uint8ArrayConsumer(arr); } else { throw new InvalidHexStringError(lowHex); } } constructor(arr, offset = 0) { this.arr = arr; this.offset = offset; } consume(count) { const subArr = this.arr.subarray(this.offset, this.offset + count); this.offset += count; return subArr; } get(idx) { return this.arr[this.offset + idx]; } length() { return this.arr.length - this.offset; } slice(start, end) { return new Uint8ArrayConsumer(this.arr.slice(start, end)); } } const isPrim = (value) => { return 'prim' in value; }; const isBytes = (value) => { return 'bytes' in value && typeof value.bytes === 'string'; }; const isString = (value) => { return 'string' in value && typeof value.string === 'string'; }; const isInt = (value) => { return 'int' in value && typeof value.int === 'string'; }; const scriptEncoder = (script) => { const code = valueEncoder(script.code); const storage = valueEncoder(script.storage); return `${pad(code.length / 2, 8)}${code}${pad(storage.length / 2, 8)}${storage}`; }; const scriptDecoder = (value) => { const code = extractRequiredLen(value); const storage = extractRequiredLen(value); return { code: valueDecoder(new Uint8ArrayConsumer(code)), storage: valueDecoder(new Uint8ArrayConsumer(storage)), }; }; const valueEncoder = (value) => { if (Array.isArray(value)) { const encoded = value.map((x) => valueEncoder(x)).join(''); const len = encoded.length / 2; return `02${pad(len)}${encoded}`; } else if (isPrim(value)) { return primEncoder(value); } else if (isBytes(value)) { return bytesEncoder(value); } else if (isString(value)) { return stringEncoder(value); } else if (isInt(value)) { return intEncoder(value); } throw new UnexpectedMichelsonValueError(JSON.stringify(value)); }; const valueDecoder = (value) => { const preamble = value.consume(1); switch (preamble[0]) { case 0x0a: return bytesDecoder(value); case 0x01: return stringDecoder(value); case 0x00: return intDecoder(value); case 0x02: { const val = new Uint8ArrayConsumer(extractRequiredLen(value)); const results = []; while (val.length() > 0) { results.push(valueDecoder(val)); } return results; } default: return primDecoder(value, preamble); } }; const extractRequiredLen = (value, bytesLength = 4) => { const len = value.consume(bytesLength); const valueLen = parseInt(Buffer.from(len).toString('hex'), 16); return value.consume(valueLen); }; /** * @description parse bytes into multiple items of an array * @param value Uint8ArrayConsumer class of forged segment to parse * @param bytesLength default 4 bytes for length of variable bytes * @returns array of Uint8Array values for each array item */ const stripLengthPrefixFromBytes = (value, bytesLength = 4) => { const ret = []; let values = value; while (values.length()) { const len = values.consume(bytesLength); const valueLen = parseInt(Buffer.from(len).toString('hex'), 16); ret.push(values.consume(valueLen)); values = values.slice(valueLen + bytesLength); } return ret; }; const bytesEncoder = (value) => { if (!/^([A-Fa-f0-9]{2})*$/.test(value.bytes)) { throw new InvalidHexStringError(value.bytes); } const len = value.bytes.length / 2; return `0a${pad(len)}${value.bytes}`; }; const bytesDecoder = (value) => { const bytes = extractRequiredLen(value); return { bytes: Buffer.from(bytes).toString('hex'), }; }; const stringEncoder = (value) => { const str = Buffer.from(value.string, 'utf8').toString('hex'); const hexLength = str.length / 2; return `01${pad(hexLength)}${str}`; }; const stringDecoder = (value) => { const str = extractRequiredLen(value); return { string: Buffer.from(str).toString('utf8'), }; }; const intEncoder = ({ int }) => { const num = new BigNumber(int, 10); const positiveMark = num.toString(2)[0] === '-' ? '1' : '0'; const binary = num.toString(2).replace(/-/g, ''); const pad = binary.length <= 6 ? 6 : (binary.length - 6) % 7 ? binary.length + 7 - ((binary.length - 6) % 7) : binary.length; const splitted = binary.padStart(pad, '0').match(/\d{6,7}/g); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const reversed = splitted.reverse(); reversed[0] = positiveMark + reversed[0]; const numHex = reversed.map((x, i) => // Add one to the last chunk parseInt((i === reversed.length - 1 ? '0' : '1') + x, 2) .toString(16) .padStart(2, '0')); return `00${numHex.join('')}`; }; const intDecoder = (value) => { let c = value.consume(1)[0]; const hexNumber = []; const isNotLastChunkMask = 1 << 7; while (c & isNotLastChunkMask) { hexNumber.push(c); c = value.consume(1)[0]; } hexNumber.push(c); const isNegative = !!((1 << 6) & hexNumber[0]); hexNumber[0] = hexNumber[0] & 0b1111111; const numBin = hexNumber .map((x, i) => x .toString(2) .slice(i === 0 ? -6 : -7) .padStart(i === 0 ? 6 : 7, '0')) .reverse(); let num = new BigNumber(numBin.join(''), 2); if (isNegative) { num = num.times(-1); } return { int: num.toFixed(), }; }; const primEncoder = (value) => { const hasAnnot = +Array.isArray(value.annots); const argsCount = Array.isArray(value.args) ? value.args.length : 0; // Specify the number of args max is 3 without annotation const preamble = pad(Math.min(2 * argsCount + hasAnnot + 0x03, 9), 2); const op = opMappingReverse[value.prim]; let encodedArgs = (value.args || []).map((arg) => valueEncoder(arg)).join(''); const encodedAnnots = Array.isArray(value.annots) ? encodeAnnots(value.annots) : ''; if ((value.prim === 'LAMBDA' || value.prim === 'LAMBDA_REC') && argsCount) { encodedArgs = pad(encodedArgs.length / 2) + encodedArgs + pad(0); } if ((value.prim === 'pair' || value.prim === 'Pair') && argsCount > 2) { encodedArgs = encodedAnnots === '' ? pad(encodedArgs.length / 2) + encodedArgs + pad(0) : pad(encodedArgs.length / 2) + encodedArgs; } if (value.prim === 'view' && value.args) { encodedArgs = pad(encodedArgs.length / 2) + encodedArgs + pad(0); } return `${preamble}${op}${encodedArgs}${encodedAnnots}`; }; const primDecoder = (value, preamble) => { const hasAnnot = (preamble[0] - 0x03) % 2 === 1; let argsCount = Math.floor((preamble[0] - 0x03) / 2); const op = value.consume(1)[0].toString(16).padStart(2, '0'); const result = { prim: opMapping[op], }; if (opMapping[op] === 'LAMBDA' || opMapping[op] === 'LAMBDA_REC') { value.consume(4); } if (opMapping[op] === 'view') { if (argsCount != 0) { return primViewDecoder(value, result); } else { return result; } } let combPairArgs; let combPairAnnots; if ((opMapping[op] === 'pair' || opMapping[op] === 'Pair') && argsCount > 2) { combPairArgs = decodeCombPair(value); argsCount = 0; combPairAnnots = decodeAnnots(value); } const args = new Array(argsCount).fill(0).map(() => valueDecoder(value)); if (opMapping[op] === 'LAMBDA' || opMapping[op] === 'LAMBDA_REC') { value.consume(4); } if (combPairArgs) { result['args'] = combPairArgs; } else if (args.length) { result['args'] = args; } if (combPairAnnots && combPairAnnots[0] !== '') { result['annots'] = combPairAnnots; } else if (hasAnnot) { result['annots'] = decodeAnnots(value); } return result; }; const primViewDecoder = (value, result) => { value.consume(4); result['args'] = new Array(4).fill(0).map(() => valueDecoder(value)); value.consume(4); return result; }; const decodeCombPair = (val) => { const array = new Uint8ArrayConsumer(extractRequiredLen(val)); const args = []; while (array.length() > 0) { args.push(valueDecoder(array)); } return args; }; const encodeAnnots = (value) => { const mergedAnnot = value .map((x) => { return Buffer.from(x, 'utf8').toString('hex'); }) .join('20'); const len = mergedAnnot.length / 2; return `${pad(len)}${mergedAnnot}`; }; const decodeAnnots = (val) => { const len = val.consume(4); const annotLen = parseInt(Buffer.from(len).toString('hex'), 16); const restOfAnnot = val.consume(annotLen); const restOfAnnotHex = Buffer.from(restOfAnnot).toString('hex'); return restOfAnnotHex.split('20').map((x) => Buffer.from(x, 'hex').toString('utf8')); }; // https://protocol.mavryk.org/shell/p2p_api.html specifies data types and structure for forging const prefixEncoder = (prefix$1) => (str) => { return buf2hex(Buffer.from(b58cdecode(str, prefix[prefix$1]))); }; const prefixDecoder = (pre) => (str) => { const val = str.consume(prefixLength[pre]); return b58cencode(val, prefix[pre]); }; const mv1Decoder = prefixDecoder(Prefix.MV1); const branchDecoder = prefixDecoder(Prefix.B); const publicKeyHashDecoder = (val) => { const prefix = val.consume(1); if (prefix[0] === 0x00) { return prefixDecoder(Prefix.MV1)(val); } else if (prefix[0] === 0x01) { return prefixDecoder(Prefix.MV2)(val); } else if (prefix[0] === 0x02) { return prefixDecoder(Prefix.MV3)(val); } }; const publicKeyHashesDecoder = (val) => { if (!boolDecoder(val)) { return undefined; } const publicKeyHashes = []; val.consume(4); while (val.length() > 0) { publicKeyHashes.push(publicKeyHashDecoder(val)); } return publicKeyHashes; }; const branchEncoder = prefixEncoder(Prefix.B); const mv1Encoder = prefixEncoder(Prefix.MV1); const boolEncoder = (bool) => (bool ? 'ff' : '00'); const proposalEncoder = (proposal) => { return prefixEncoder(Prefix.P)(proposal); }; const proposalDecoder = (proposal) => { return prefixDecoder(Prefix.P)(proposal); }; const proposalsDecoder = (proposal) => { const proposals = []; proposal.consume(4); while (proposal.length() > 0) { proposals.push(proposalDecoder(proposal)); } return proposals; }; const proposalsEncoder = (proposals) => { return pad(32 * proposals.length) + proposals.map((x) => proposalEncoder(x)).join(''); }; const ballotEncoder = (ballot) => { switch (ballot) { case 'yay': return '00'; case 'nay': return '01'; case 'pass': return '02'; default: throw new InvalidBallotValueError(ballot); } }; const ballotDecoder = (ballot) => { const value = ballot.consume(1); switch (value[0]) { case 0x00: return 'yay'; case 0x01: return 'nay'; case 0x02: return 'pass'; default: throw new DecodeBallotValueError(value[0].toString()); } }; const pvmKindEncoder = (pvm) => { switch (pvm) { case 'arith': return '00'; case 'wasm_2_0_0': return '01'; case 'riscv': return '02'; default: throw new UnsupportedPvmKindError(pvm); } }; const pvmKindDecoder = (pvm) => { const value = pvm.consume(1); switch (value[0]) { case 0x00: return 'arith'; case 0x01: return 'wasm_2_0_0'; case 0x02: return 'riscv'; default: throw new DecodePvmKindError(value[0].toString()); } }; const delegateEncoder = (val) => { if (val) { return boolEncoder(true) + publicKeyHashEncoder(val); } else { return boolEncoder(false); } }; const int32Encoder = (val) => { const num = parseInt(String(val), 10); const byte = []; for (let i = 0; i < 4; i++) { const shiftBy = (4 - (i + 1)) * 8; byte.push((num & (0xff << shiftBy)) >> shiftBy); } return Buffer.from(byte).toString('hex'); }; const int32Decoder = (val) => { const num = val.consume(4); let finalNum = 0; for (let i = 0; i < num.length; i++) { finalNum = finalNum | (num[i] << ((num.length - (i + 1)) * 8)); } return finalNum; }; const int16Encoder = (val) => { const num = parseInt(String(val), 10); const byte = []; for (let i = 0; i < 2; i++) { const shiftBy = (2 - (i + 1)) * 8; byte.push((num & (0xff << shiftBy)) >> shiftBy); } return Buffer.from(byte).toString('hex'); }; const int16Decoder = (val) => { const num = val.consume(2); let finalNum = 0; for (let i = 0; i < num.length; i++) { finalNum = finalNum | (num[i] << ((num.length - (i + 1)) * 8)); } return finalNum; }; const boolDecoder = (val) => { const bool = val.consume(1); return bool[0] === 0xff; }; const delegateDecoder = (val) => { const hasDelegate = boolDecoder(val); if (hasDelegate) { return publicKeyHashDecoder(val); } }; const publicKeyHashEncoder = (val) => { const pubkeyPrefix = val.substring(0, 3); switch (pubkeyPrefix) { case Prefix.MV1: return '00' + prefixEncoder(Prefix.MV1)(val); case Prefix.MV2: return '01' + prefixEncoder(Prefix.MV2)(val); case Prefix.MV3: return '02' + prefixEncoder(Prefix.MV3)(val); case Prefix.MV4: return '03' + prefixEncoder(Prefix.MV4)(val); default: throw new InvalidKeyHashError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting one for the following "${Prefix.MV1}", "${Prefix.MV2}", "${Prefix.MV3}" or "${Prefix.MV4}".`); } }; const publicKeyHashesEncoder = (val) => { if (!val) { return boolEncoder(false); } if (val.length === 0) { return boolEncoder(true) + pad(0); } const publicKeyHashes = val.reduce((prev, curr) => { return prev + publicKeyHashEncoder(curr); }, ''); return boolEncoder(true) + pad(publicKeyHashes.length / 2) + publicKeyHashes; }; const publicKeyEncoder = (val) => { const pubkeyPrefix = val.substring(0, 4); switch (pubkeyPrefix) { case Prefix.EDPK: return '00' + prefixEncoder(Prefix.EDPK)(val); case Prefix.SPPK: return '01' + prefixEncoder(Prefix.SPPK)(val); case Prefix.P2PK: return '02' + prefixEncoder(Prefix.P2PK)(val); default: throw new InvalidPublicKeyError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting one of the following '${Prefix.EDPK}', '${Prefix.SPPK}', '${Prefix.P2PK}' or '${Prefix.BLPK}'.`); } }; const addressEncoder = (val) => { const pubkeyPrefix = val.substring(0, 3); switch (pubkeyPrefix) { case Prefix.MV1: case Prefix.MV2: case Prefix.MV3: case Prefix.MV4: return '00' + publicKeyHashEncoder(val); case Prefix.KT1: return '01' + prefixEncoder(Prefix.KT1)(val) + '00'; default: throw new InvalidAddressError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting one of the following prefix '${Prefix.MV1}', ${Prefix.MV2}', '${Prefix.MV3}', '${Prefix.MV4}' or '${Prefix.KT1}'.`); } }; const smartRollupAddressEncoder = (val) => { if (val.substring(0, 3) !== Prefix.SR1) { throw new InvalidSmartRollupAddressError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SR1}'.`); } return prefixEncoder(Prefix.SR1)(val); }; const smartContractAddressEncoder = (val) => { const prefix = val.substring(0, 3); if (prefix === Prefix.KT1) { return '01' + prefixEncoder(Prefix.KT1)(val) + '00'; } throw new InvalidContractAddressError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.KT1}'.`); }; const publicKeyDecoder = (val) => { const preamble = val.consume(1); switch (preamble[0]) { case 0x00: return prefixDecoder(Prefix.EDPK)(val); case 0x01: return prefixDecoder(Prefix.SPPK)(val); case 0x02: return prefixDecoder(Prefix.P2PK)(val); default: throw new InvalidPublicKeyError(val.toString(), invalidDetail(ValidationResult.NO_PREFIX_MATCHED)); } }; const smartRollupCommitmentHashEncoder = (val) => { const prefix = val.substring(0, 4); if (prefix === Prefix.SRC1) { return prefixEncoder(Prefix.SRC1)(val); } throw new InvalidSmartRollupCommitmentHashError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SRC1}'`); }; const addressDecoder = (val) => { const preamble = val.consume(1); switch (preamble[0]) { case 0x00: return publicKeyHashDecoder(val); case 0x01: { const address = prefixDecoder(Prefix.KT1)(val); val.consume(1); return address; } default: throw new InvalidAddressError(val.toString(), ': Unable to decode.'); } }; const smartRollupAddressDecoder = (val) => { const address = prefixDecoder(Prefix.SR1)(val); if (address.substring(0, 3) !== Prefix.SR1) { throw new InvalidSmartRollupAddressError(address, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SR1}'.`); } return address; }; const smartContractAddressDecoder = (val) => { const preamble = val.consume(1); if (preamble[0] === 0x01) { const scAddress = prefixDecoder(Prefix.KT1)(val); val.consume(1); return scAddress; } throw new InvalidContractAddressError(val.toString(), invalidDetail(ValidationResult.NO_PREFIX_MATCHED)); }; const smartRollupCommitmentHashDecoder = (val) => { const address = prefixDecoder(Prefix.SRC1)(val); if (address.substring(0, 4) !== Prefix.SRC1) { throw new InvalidSmartRollupCommitmentHashError(address, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SRC1}'`); } return address; }; const zarithEncoder = (n) => { const fn = []; let nn = new BigNumber$1(n, 10); if (nn.isNaN()) { throw new TypeError(`Invalid zarith number ${n}`); } // eslint-disable-next-line no-constant-condition while (true) { if (nn.lt(128)) { if (nn.lt(16)) fn.push('0'); fn.push(nn.toString(16)); break; } else { let b = nn.mod(128); nn = nn.minus(b); nn = nn.dividedBy(128); b = b.plus(128); fn.push(b.toString(16)); } } return fn.join(''); }; const zarithDecoder = (n) => { let mostSignificantByte = 0; while (mostSignificantByte < n.length() && (n.get(mostSignificantByte) & 128) !== 0) { mostSignificantByte += 1; } let num = new BigNumber$1(0); for (let i = mostSignificantByte; i >= 0; i -= 1) { const tmp = n.get(i) & 0x7f; num = num.multipliedBy(128); num = num.plus(tmp); } n.consume(mostSignificantByte + 1); return new BigNumber$1(num).toString(); }; const entrypointDecoder = (value) => { const preamble = pad(value.consume(1)[0], 2); if (preamble in entrypointMapping) { return entrypointMapping[preamble]; } else { const entry = extractRequiredLen(value, 1); const entrypoint = Buffer.from(entry).toString('utf8'); if (entrypoint.length > ENTRYPOINT_MAX_LENGTH) { throw new OversizedEntryPointError(entrypoint); } return entrypoint; } }; const parametersDecoder = (val) => { const preamble = val.consume(1); if (preamble[0] === 0x00) { return; } else { const encodedEntrypoint = entrypointDecoder(val); const params = extractRequiredLen(val); const parameters = valueDecoder(new Uint8ArrayConsumer(params)); return { entrypoint: encodedEntrypoint, value: parameters, }; } }; const entrypointEncoder = (entrypoint) => { if (entrypoint in entrypointMappingReverse) { return `${entrypointMappingReverse[entrypoint]}`; } else { if (entrypoint.length > ENTRYPOINT_MAX_LENGTH) { throw new OversizedEntryPointError(entrypoint); } const value = { string: entrypoint }; return `ff${valueEncoder(value).slice(8)}`; } }; const parametersEncoder = (val) => { if (!val || (val.entrypoint === 'default' && 'prim' in val.value && val.value.prim === 'Unit')) { return '00'; } const encodedEntrypoint = entrypointEncoder(val.entrypoint); const parameters = valueEncoder(val.value); const length = pad(parameters.length / 2); return `ff${encodedEntrypoint}${length}${parameters}`; }; const valueParameterEncoder = (value) => { const valueEncoded = valueEncoder(value); return `${pad(valueEncoded.length / 2)}${valueEncoded}`; }; const valueParameterDecoder = (val) => { const value = extractRequiredLen(val); return valueDecoder(new Uint8ArrayConsumer(value)); }; const blockPayloadHashEncoder = prefixEncoder(Prefix.VH); const blockPayloadHashDecoder = prefixDecoder(Prefix.VH); const entrypointNameEncoder = (entrypoint) => { const value = { string: entrypoint }; return `${valueEncoder(value).slice(2)}`; }; const entrypointNameDecoder = (val) => { const entry = extractRequiredLen(val); return Buffer.from(entry).toString('utf8'); }; const burnLimitEncoder = (val) => { return !val ? '00' : `ff${zarithEncoder(val)}`; }; const burnLimitDecoder = (value) => { const prefix = value.consume(1); if (Buffer.from(prefix).toString('hex') !== '00') { return zarithDecoder(value); } }; const depositsLimitEncoder = (val) => { return !val ? '00' : `ff${zarithEncoder(val)}`; }; const depositsLimitDecoder = (value) => { const prefix = value.consume(1); if (Buffer.from(prefix).toString('hex') !== '00') { return zarithDecoder(value); } }; const paddedBytesEncoder = (val, paddingLength = 8) => { return `${pad(val.length / 2, paddingLength)}${val}`; }; const paddedBytesDecoder = (val) => { const value = extractRequiredLen(val); return Buffer.from(value).toString('hex'); }; const smartRollupMessageEncoder = (val) => { const message = val.reduce((prev, curr) => { return prev + `${pad(curr.length / 2)}${curr}`; }, ''); return `${pad(message.length / 2)}${message}`; }; const smartRollupMessageDecoder = (val) => { const valueArray = extractRequiredLen(val); const ret = stripLengthPrefixFromBytes(new Uint8ArrayConsumer(valueArray)); return ret.map((value) => Buffer.from(value).toString('hex')); }; const dalCommitmentEncoder = (val) => { const prefix = val.substring(0, 2); if (prefix === Prefix.SH) { return prefixEncoder(Prefix.SH)(val); } throw new InvalidDalCommitmentError(val, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SH}'`); }; const dalCommitmentDecoder = (val) => { const commitment = prefixDecoder(Prefix.SH)(val); if (commitment.substring(0, 2) !== Prefix.SH) { throw new InvalidDalCommitmentError(commitment, invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` expecting prefix '${Prefix.SH}'`); } return commitment; }; const slotHeaderEncoder = (val) => { return pad(val.slot_index, 2) + dalCommitmentEncoder(val.commitment) + val.commitment_proof; }; const slotHeaderDecoder = (val) => { const preamble = val.consume(1); return { slot_index: Number(preamble[0].toString(10)), commitment: dalCommitmentDecoder(val), commitment_proof: toHexString(val.consume(96)), // rpcForger expect commitment_proof bytes to be len 96 }; }; const ManagerOperationSchema = { branch: CODEC.BRANCH, contents: [CODEC.OPERATION], }; const ActivationSchema = { pkh: CODEC.MV1, secret: CODEC.SECRET, }; const RevealSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, public_key: CODEC.PUBLIC_KEY, }; const DelegationSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, delegate: CODEC.DELEGATE, }; const TransactionSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, amount: CODEC.ZARITH, destination: CODEC.ADDRESS, parameters: CODEC.PARAMETERS, }; const OriginationSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, balance: CODEC.ZARITH, delegate: CODEC.DELEGATE, script: CODEC.SCRIPT, }; const BallotSchema = { source: CODEC.PKH, period: CODEC.INT32, proposal: CODEC.PROPOSAL, ballot: CODEC.BALLOT_STATEMENT, }; const AttestationSchema = { slot: CODEC.INT16, level: CODEC.INT32, round: CODEC.INT32, block_payload_hash: CODEC.BLOCK_PAYLOAD_HASH, }; const AttestationWithDalSchema = { slot: CODEC.INT16, level: CODEC.INT32, round: CODEC.INT32, block_payload_hash: CODEC.BLOCK_PAYLOAD_HASH, dal_attestation: CODEC.ZARITH, }; const SeedNonceRevelationSchema = { level: CODEC.INT32, nonce: CODEC.RAW, }; const ProposalsSchema = { source: CODEC.PKH, period: CODEC.INT32, proposals: CODEC.PROPOSAL_ARR, }; const RegisterGlobalConstantSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, value: CODEC.VALUE, }; const TransferTicketSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, ticket_contents: CODEC.VALUE, ticket_ty: CODEC.VALUE, ticket_ticketer: CODEC.ADDRESS, ticket_amount: CODEC.ZARITH, destination: CODEC.ADDRESS, entrypoint: CODEC.ENTRYPOINT, }; const IncreasePaidStorageSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, amount: CODEC.ZARITH, destination: CODEC.SMART_CONTRACT_ADDRESS, }; const UpdateConsensusKeySchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, pk: CODEC.PUBLIC_KEY, }; const DrainDelegateSchema = { consensus_key: CODEC.PKH, delegate: CODEC.PKH, destination: CODEC.PKH, }; const SetDepositsLimitSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, limit: CODEC.DEPOSITS_LIMIT, }; const SmartRollupOriginateSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, pvm_kind: CODEC.PVM_KIND, kernel: CODEC.PADDED_BYTES, parameters_ty: CODEC.VALUE, whitelist: CODEC.PKH_ARR, }; const SmartRollupAddMessagesSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, message: CODEC.SMART_ROLLUP_MESSAGE, }; const SmartRollupExecuteOutboxMessageSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, rollup: CODEC.SMART_ROLLUP_ADDRESS, cemented_commitment: CODEC.SMART_ROLLUP_COMMITMENT_HASH, output_proof: CODEC.PADDED_BYTES, }; const DalPublishCommitmentSchema = { source: CODEC.PKH, fee: CODEC.ZARITH, counter: CODEC.ZARITH, gas_limit: CODEC.ZARITH, storage_limit: CODEC.ZARITH, slot_header: CODEC.SLOT_HEADER, }; const FailingNoopSchema = { arbitrary: CODEC.PADDED_BYTES, }; const operationEncoder = (encoders) => (operation) => { if (!(operation.kind in encoders) || !(operation.kind in kindMappingReverse)) { throw new InvalidOperationKindError(operation.kind); } return kindMappingReverse[operation.kind] + encoders[operation.kind](operation); }; const operationDecoder = (decoders) => (value) => { const op = value.consume(1); const operationName = kindMapping[op[0]]; if (operationName === undefined) { throw new UnsupportedOperationError(op[0].toString()); } const decodedObj = decoders[operationName](value); if (typeof decodedObj !== 'object') { throw new OperationDecodingError('Invalid operation, cannot be decoded.'); } return Object.assign({ kind: operationName }, decodedObj); }; const schemaEncoder = (encoders) => (schema) => (value) => { const keys = Object.keys(schema); return keys.reduce((prev, key) => { const valueToEncode = schema[key]; if (value && Array.isArray(valueToEncode)) { const encoder = encoders[valueToEncode[0]]; const values = value[key]; if (!Array.isArray(values)) { throw new OperationEncodingError(`Invalid operation value "${JSON.stringify(values)}" of key "${key}, expected value to be Array.`); } return (prev + values.reduce((prevBytes, current) => prevBytes + encoder(current), '')); } else { const encoder = encoders[valueToEncode]; return prev + encoder(value[key]); } }, ''); }; const schemaDecoder = (decoders) => (schema) => (value) => { const keys = Object.keys(schema); return keys.reduce((prev, key) => { const valueToEncode = schema[key]; if (Array.isArray(valueToEncode)) { const decoder = decoders[valueToEncode[0]]; const decoded = []; const lastLength = value.length(); while (value.length() > 0) { decoded.push(decoder(value)); if (lastLength === value.length()) { throw new OperationDecodingError('Unable to decode value'); } } return Object.assign(Object.assign({}, prev), { [key]: decoded }); } else { const decoder = decoders[valueToEncode]; const result = decoder(value); if (typeof result !== 'undefined') { return Object.assign(Object.assign({}, prev), { [key]: result }); } else { return Object.assign({}, prev); } } }, {}); }; const decoders = { [CODEC.SECRET]: (val) => toHexString(val.consume(20)), [CODEC.RAW]: (val) => toHexString(val.consume(32)), [CODEC.MV1]: mv1Decoder, [CODEC.BRANCH]: branchDecoder, [CODEC.ZARITH]: zarithDecoder, [CODEC.PUBLIC_KEY]: publicKeyDecoder, [CODEC.PKH]: publicKeyHashDecoder, [CODEC.PKH_ARR]: publicKeyHashesDecoder, [CODEC.DELEGATE]: delegateDecoder, [CODEC.INT32]: int32Decoder, [CODEC.SCRIPT]: scriptDecoder, [CODEC.BALLOT_STATEMENT]: ballotDecoder, [CODEC.PROPOSAL]: proposalDecoder, [CODEC.PROPOSAL_ARR]: proposalsDecoder, [CODEC.PARAMETERS]: parametersDecoder, [CODEC.ADDRESS]: addressDecoder, [CODEC.SMART_ROLLUP_ADDRESS]: smartRollupAddressDecoder, [CODEC.SMART_CONTRACT_ADDRESS]: smartContractAddressDecoder, [CODEC.SMART_ROLLUP_COMMITMENT_HASH]: smartRollupCommitmentHashDecoder, [CODEC.VALUE]: valueParameterDecoder, [CODEC.INT16]: int16Decoder, [CODEC.BLOCK_PAYLOAD_HASH]: blockPayloadHashDecoder, [CODEC.ENTRYPOINT]: entrypointNameDecoder, [CODEC.BURN_LIMIT]: burnLimitDecoder, [CODEC.DEPOSITS_LIMIT]: depositsLimitDecoder, [CODEC.PVM_KIND]: pvmKindDecoder, [CODEC.PADDED_BYTES]: paddedBytesDecoder, [CODEC.SMART_ROLLUP_MESSAGE]: smartRollupMessageDecoder, [CODEC.SLOT_HEADER]: slotHeaderDecoder, }; decoders[CODEC.OPERATION] = operationDecoder(decoders); decoders[CODEC.OP_ACTIVATE_ACCOUNT] = (val) => schemaDecoder(decoders)(ActivationSchema)(val); decoders[CODEC.OP_FAILING_NOOP] = (val) => schemaDecoder(decoders)(FailingNoopSchema)(val); decoders[CODEC.OP_DELEGATION] = (val) => schemaDecoder(decoders)(DelegationSchema)(val); decoders[CODEC.OP_TRANSACTION] = (val) => schemaDecoder(decoders)(TransactionSchema)(val); decoders[CODEC.OP_ORIGINATION] = (val) => schemaDecoder(decoders)(OriginationSchema)(val); decoders[CODEC.OP_BALLOT] = (val) => schemaDecoder(decoders)(BallotSchema)(val); decoders[CODEC.OP_ATTESTATION] = (val) => schemaDecoder(decoders)(AttestationSchema)(val); decoders[CODEC.OP_ATTESTATION_WITH_DAL] = (val) => schemaDecoder(decoders)(AttestationWithDalSchema)(val); decoders[CODEC.OP_SEED_NONCE_REVELATION] = (val) => schemaDecoder(decoders)(SeedNonceRevelationSchema)(val); decoders[CODEC.OP_PROPOSALS] = (val) => schemaDecoder(decoders)(ProposalsSchema)(val); decoders[CODEC.OP_REVEAL] = (val) => schemaDecoder(decoders)(RevealSchema)(val); decoders[CODEC.OP_REGISTER_GLOBAL_CONSTANT] = (val) => schemaDecoder(decoders)(RegisterGlobalConstantSchema)(val); decoders[CODEC.OP_TRANSFER_TICKET] = (val) => schemaDecoder(decoders)(TransferTicketSchema)(val); decoders[CODEC.OP_INCREASE_PAID_STORAGE] = (val) => schemaDecoder(decoders)(IncreasePaidStorageSchema)(val); decoders[CODEC.OP_UPDATE_CONSENSUS_KEY] = (val) => schemaDecoder(decoders)(UpdateConsensusKeySchema)(val); decoders[CODEC.OP_DRAIN_DELEGATE] = (val) => schemaDecoder(decoders)(DrainDelegateSchema)(val); decoders[CODEC.OP_SMART_ROLLUP_ORIGINATE] = (val) => schemaDecoder(decoders)(SmartRollupOriginateSchema)(val); decoders[CODEC.OP_SMART_ROLLUP_ADD_MESSAGES] = (val) => schemaDecoder(decoders)(SmartRollupAddMessagesSchema)(val); decoders[CODEC.OP_SMART_ROLLUP_EXECUTE_OUTBOX_MESSAGE] = (val) => schemaDecoder(decoders)(SmartRollupExecuteOutboxMessageSchema)(val); decoders[CODEC.OP_DAL_PUBLISH_COMMITMENT] = (val) => schemaDecoder(decoders)(DalPublishCommitmentSchema)(val); decoders[CODEC.MANAGER] = schemaDecoder(decoders)(ManagerOperationSchema); decoders[CODEC.OP_SET_DEPOSITS_LIMIT] = (val) => schemaDecoder(decoders)(SetDepositsLimitSchema)(val); const encoders = { [CODEC.SECRET]: (val) => val, [CODEC.RAW]: (val) => val, [CODEC.MV1]: mv1Encoder, [CODEC.BRANCH]: branchEncoder, [CODEC.ZARITH]: zarithEncoder, [CODEC.PUBLIC_KEY]: publicKeyEncoder, [CODEC.PKH]: publicKeyHashEncoder, [CODEC.PKH_ARR]: publicKeyHashesEncoder, [CODEC.DELEGATE]: delegateEncoder, [CODEC.SCRIPT]: scriptEncoder, [CODEC.BALLOT_STATEMENT]: ballotEncoder, [CODEC.PROPOSAL]: proposalEncoder, [CODEC.PROPOSAL_ARR]: proposalsEncoder, [CODEC.INT32]: int32Encoder, [CODEC.PARAMETERS]: parametersEncoder, [CODEC.ADDRESS]: addressEncoder, [CODEC.SMART_ROLLUP_ADDRESS]: smartRollupAddressEncoder, [CODEC.SMART_CONTRACT_ADDRESS]: smartContractAddressEncoder, [CODEC.SMART_ROLLUP_COMMITMENT_HASH]: smartRollupCommitmentHashEncoder, [CODEC.VALUE]: valueParameterEncoder, [C