@mavrykdynamics/taquito-local-forging
Version:
Provide local forging functionality to be with taquito
1,492 lines (1,483 loc) • 57.8 kB
JavaScript
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