morphit/node_modules/@beblurt/dblurt/lib/chain/serializer.js
Morphit Team 24240cef4c
Some checks failed
morphit-release / Build + publish release tarball (push) Has been cancelled
Reputation flags clearable across all four signals; names and avatars stop vanishing
2026-07-23 14:28:04 -07:00

461 lines
16 KiB
JavaScript

"use strict";
/**
* @file Blurt protocol serialization.
* @author Johan Nordberg <code@johan-nordberg.com>
* @license
* Copyright (c) 2017 Johan Nordberg. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You acknowledge that this software is not designed, licensed or intended for use
* in the design, construction, operation or maintenance of any military facility.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Types = void 0;
const crypto_1 = require("../crypto");
const asset_1 = require("./asset");
const misc_1 = require("./misc");
// The package's Node entry point still calls deprecated `Buffer()`; this build has the same API.
const RuntimeByteBuffer = require('bytebuffer/dist/bytebuffer');
const PublicKeySerializer = (buffer, data) => {
if (data === null || (typeof data === 'string' && data.endsWith('1111111111111111111111111111111114T1Anm'))) {
buffer.append(Buffer.alloc(33, 0));
}
else {
buffer.append(crypto_1.PublicKey.from(data).key);
}
};
/** Basic */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const VoidSerializer = (buffer) => {
throw new Error('Void can not be serialized');
};
const StringSerializer = (buffer, data) => {
buffer.writeVString(data);
};
const DateSerializer = (buffer, data) => {
buffer.writeUint32(Math.floor(new Date(data + 'Z').getTime() / 1000));
};
const BooleanSerializer = (buffer, data) => {
buffer.writeByte(data ? 1 : 0);
};
// eslint-disable-next-line max-len
const FlatMapSerializer = (keySerializer, valueSerializer) => (buffer, data) => {
buffer.writeVarint32(data.length);
for (const [key, value] of data) {
keySerializer(buffer, key);
valueSerializer(buffer, value);
}
};
const ArraySerializer = (itemSerializer) => (buffer, data) => {
buffer.writeVarint32(data.length);
for (const item of data) {
itemSerializer(buffer, item);
}
};
const StaticVariantSerializer = (itemSerializers) => (buffer, data) => {
const [id, item] = data;
buffer.writeVarint32(id);
itemSerializers[id](buffer, item);
};
/** Serialize asset exactly in protocol smallest units. */
const AssetSerializer = (buffer, data) => {
const asset = asset_1.Asset.from(data).symbols();
const precision = asset.getPrecision();
buffer.writeInt64(RuntimeByteBuffer.Long.fromString(asset.toSmallestUnitString()));
buffer.writeUint8(precision);
for (let i = 0; i < 7; i++) {
buffer.writeUint8(asset.symbol.charCodeAt(i) || 0);
}
};
const BinarySerializer = (size) => (buffer, data) => {
data = misc_1.HexBuffer.from(data);
const len = data.buffer.length;
if (size) {
if (len !== size) {
throw new Error(`Unable to serialize binary. Expected ${size} bytes, got ${len}`);
}
}
else {
buffer.writeVarint32(len);
}
buffer.append(data.buffer);
};
const VariableBinarySerializer = BinarySerializer();
/** Int */
const Int8Serializer = (buffer, data) => {
buffer.writeInt8(data);
};
const Int16Serializer = (buffer, data) => {
buffer.writeInt16(data);
};
const Int32Serializer = (buffer, data) => {
buffer.writeInt32(data);
};
const Int64Serializer = (buffer, data) => {
buffer.writeInt64(data);
};
/** Uint */
const UInt8Serializer = (buffer, data) => {
buffer.writeUint8(data);
};
const UInt16Serializer = (buffer, data) => {
buffer.writeUint16(data);
};
const UInt32Serializer = (buffer, data) => {
buffer.writeUint32(data);
};
const UInt64Serializer = (buffer, data) => {
buffer.writeUint64(data);
};
/** Serializer */
const OperationDataSerializer = (operationId, definitions) => {
const objectSerializer = ObjectSerializer(definitions);
return (buffer, data) => {
buffer.writeVarint32(operationId);
objectSerializer(buffer, data);
};
};
// eslint-disable-next-line max-len
const ObjectSerializer = (keySerializers) => (buffer, data) => {
for (const [key, serializer] of keySerializers) {
try {
serializer(buffer, data[key]);
}
catch (error) {
error.message = `${key}: ${error.message}`;
throw error;
}
}
};
const EncryptedMemoSerializer = ObjectSerializer([
['from', PublicKeySerializer],
['to', PublicKeySerializer],
['nonce', UInt64Serializer],
['check', UInt32Serializer],
['encrypted', BinarySerializer()]
]);
const OptionalSerializer = (valueSerializer) => (buffer, data) => {
if (data) {
buffer.writeByte(1);
valueSerializer(buffer, data);
}
else {
buffer.writeByte(0);
}
};
const AuthoritySerializer = ObjectSerializer([
['weight_threshold', UInt32Serializer],
['account_auths', FlatMapSerializer(StringSerializer, UInt16Serializer)],
['key_auths', FlatMapSerializer(PublicKeySerializer, UInt16Serializer)]
]);
const BeneficiarySerializer = ObjectSerializer([
['account', StringSerializer],
['weight', UInt16Serializer]
]);
const WitnessUpdatePropertiesSerializer = ObjectSerializer([
['account_creation_fee', AssetSerializer],
// ['account_subsidy_budget', UInt32Serializer],
// ['account_subsidy_decay', UInt32Serializer],
// ['bandwidth_kbytes_fee', AssetSerializer],
['maximum_block_size', UInt32Serializer]
// ['operation_flat_fee', AssetSerializer],
// ['proposal_fee', AssetSerializer],
]);
/**
* START | Operation Serializers
*/
const OperationSerializers = {};
OperationSerializers.account_create = OperationDataSerializer(5, [
['fee', AssetSerializer],
['creator', StringSerializer],
['new_account_name', StringSerializer],
['owner', AuthoritySerializer],
['active', AuthoritySerializer],
['posting', AuthoritySerializer],
['memo_key', PublicKeySerializer],
['json_metadata', StringSerializer]
]);
/** update for blurt's account_update */
OperationSerializers.account_update = OperationDataSerializer(6, [
['account', StringSerializer],
['owner', OptionalSerializer(AuthoritySerializer)],
['active', OptionalSerializer(AuthoritySerializer)],
['posting', OptionalSerializer(AuthoritySerializer)],
['memo_key', OptionalSerializer(PublicKeySerializer)],
['json_metadata', StringSerializer],
['posting_json_metadata', StringSerializer],
['extensions', ArraySerializer(StringSerializer)]
]);
OperationSerializers.account_witness_vote = OperationDataSerializer(8, [
['account', StringSerializer],
['witness', StringSerializer],
['approve', BooleanSerializer]
]);
OperationSerializers.account_witness_proxy = OperationDataSerializer(9, [
['account', StringSerializer],
['proxy', StringSerializer]
]);
OperationSerializers.change_recovery_account = OperationDataSerializer(19, [
['account_to_recover', StringSerializer],
['new_recovery_account', StringSerializer],
['extensions', ArraySerializer(StringSerializer)]
]);
OperationSerializers.claim_account = OperationDataSerializer(15, [
['creator', StringSerializer],
['fee', AssetSerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.create_claimed_account = OperationDataSerializer(16, [
['creator', StringSerializer],
['new_account_name', StringSerializer],
['owner', AuthoritySerializer],
['active', AuthoritySerializer],
['posting', AuthoritySerializer],
['memo_key', PublicKeySerializer],
['json_metadata', StringSerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.claim_reward_balance = OperationDataSerializer(31, [
['account', StringSerializer],
['reward_blurt', AssetSerializer],
['reward_vests', AssetSerializer]
]);
OperationSerializers.cancel_transfer_from_savings = OperationDataSerializer(26, [
['from', StringSerializer],
['request_id', UInt32Serializer]
]);
OperationSerializers.comment = OperationDataSerializer(1, [
['parent_author', StringSerializer],
['parent_permlink', StringSerializer],
['author', StringSerializer],
['permlink', StringSerializer],
['title', StringSerializer],
['body', StringSerializer],
['json_metadata', StringSerializer]
]);
OperationSerializers.comment_options = OperationDataSerializer(13, [
['author', StringSerializer],
['permlink', StringSerializer],
['max_accepted_payout', AssetSerializer],
['allow_votes', BooleanSerializer],
['allow_curation_rewards', BooleanSerializer],
[
'extensions',
ArraySerializer(StaticVariantSerializer([
ObjectSerializer([
['beneficiaries', ArraySerializer(BeneficiarySerializer)]
]),
ObjectSerializer([
['percent_blurt', UInt16Serializer]
])
]))
]
]);
OperationSerializers.custom_json = OperationDataSerializer(12, [
['required_auths', ArraySerializer(StringSerializer)],
['required_posting_auths', ArraySerializer(StringSerializer)],
['id', StringSerializer],
['json', StringSerializer]
]);
OperationSerializers.delete_comment = OperationDataSerializer(11, [
['author', StringSerializer],
['permlink', StringSerializer]
]);
OperationSerializers.delegate_vesting_shares = OperationDataSerializer(32, [
['delegator', StringSerializer],
['delegatee', StringSerializer],
['vesting_shares', AssetSerializer]
]);
OperationSerializers.escrow_transfer = OperationDataSerializer(20, [
['from', StringSerializer],
['to', StringSerializer],
['blurt_amount', AssetSerializer],
['escrow_id', UInt32Serializer],
['agent', StringSerializer],
['fee', AssetSerializer],
['json_meta', StringSerializer],
['ratification_deadline', DateSerializer],
['escrow_expiration', DateSerializer]
]);
OperationSerializers.escrow_approve = OperationDataSerializer(23, [
['from', StringSerializer],
['to', StringSerializer],
['agent', StringSerializer],
['who', StringSerializer],
['escrow_id', UInt32Serializer],
['approve', BooleanSerializer]
]);
OperationSerializers.escrow_dispute = OperationDataSerializer(21, [
['from', StringSerializer],
['to', StringSerializer],
['agent', StringSerializer],
['who', StringSerializer],
['escrow_id', UInt32Serializer]
]);
OperationSerializers.escrow_release = OperationDataSerializer(22, [
['from', StringSerializer],
['to', StringSerializer],
['agent', StringSerializer],
['who', StringSerializer],
['receiver', StringSerializer],
['escrow_id', UInt32Serializer],
['blurt_amount', AssetSerializer]
]);
OperationSerializers.transfer = OperationDataSerializer(2, [
['from', StringSerializer],
['to', StringSerializer],
['amount', AssetSerializer],
['memo', StringSerializer]
]);
OperationSerializers.transfer_to_vesting = OperationDataSerializer(3, [
['from', StringSerializer],
['to', StringSerializer],
['amount', AssetSerializer]
]);
OperationSerializers.withdraw_vesting = OperationDataSerializer(4, [
['account', StringSerializer],
['vesting_shares', AssetSerializer]
]);
OperationSerializers.set_withdraw_vesting_route = OperationDataSerializer(14, [
['from_account', StringSerializer],
['to_account', StringSerializer],
['percent', UInt16Serializer],
['auto_vest', BooleanSerializer]
]);
OperationSerializers.transfer_to_savings = OperationDataSerializer(24, [
['from', StringSerializer],
['to', StringSerializer],
['amount', AssetSerializer],
['memo', StringSerializer]
]);
OperationSerializers.transfer_from_savings = OperationDataSerializer(25, [
['from', StringSerializer],
['request_id', UInt32Serializer],
['to', StringSerializer],
['amount', AssetSerializer],
['memo', StringSerializer]
]);
OperationSerializers.vote = OperationDataSerializer(0, [
['voter', StringSerializer],
['author', StringSerializer],
['permlink', StringSerializer],
['weight', Int16Serializer]
]);
OperationSerializers.witness_update = OperationDataSerializer(7, [
['owner', StringSerializer],
['url', StringSerializer],
['block_signing_key', PublicKeySerializer],
['props', WitnessUpdatePropertiesSerializer],
['fee', AssetSerializer]
]);
OperationSerializers.witness_set_properties = OperationDataSerializer(33, [
['owner', StringSerializer],
['props', FlatMapSerializer(StringSerializer, VariableBinarySerializer)],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.create_proposal = OperationDataSerializer(34, [
['creator', StringSerializer],
['receiver', StringSerializer],
['start_date', DateSerializer],
['end_date', DateSerializer],
['daily_pay', AssetSerializer],
['subject', StringSerializer],
['permlink', StringSerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.update_proposal_votes = OperationDataSerializer(35, [
['voter', StringSerializer],
['proposal_ids', ArraySerializer(Int64Serializer)],
['approve', BooleanSerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.remove_proposal = OperationDataSerializer(36, [
['proposal_owner', StringSerializer],
['proposal_ids', ArraySerializer(Int64Serializer)],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.request_account_recovery = OperationDataSerializer(17, [
['recovery_account', StringSerializer],
['account_to_recover', StringSerializer],
['new_owner_authority', AuthoritySerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
OperationSerializers.recover_account = OperationDataSerializer(18, [
['account_to_recover', StringSerializer],
['new_owner_authority', AuthoritySerializer],
['recent_owner_authority', AuthoritySerializer],
['extensions', ArraySerializer(VoidSerializer)]
]);
/**
* END | Operation Serializers
*/
const OperationSerializer = (buffer, operation) => {
const serializer = OperationSerializers[operation[0]];
if (!serializer) {
throw new Error(`No serializer for operation: ${operation[0]}`);
}
try {
serializer(buffer, operation[1]);
}
catch (error) {
error.message = `${operation[0]}: ${error.message}`;
throw error;
}
};
const TransactionSerializer = ObjectSerializer([
['ref_block_num', UInt16Serializer],
['ref_block_prefix', UInt32Serializer],
['expiration', DateSerializer],
['operations', ArraySerializer(OperationSerializer)],
['extensions', ArraySerializer(StringSerializer)]
]);
exports.Types = {
Array: ArraySerializer,
Asset: AssetSerializer,
Authority: AuthoritySerializer,
Binary: BinarySerializer,
Boolean: BooleanSerializer,
Date: DateSerializer,
FlatMap: FlatMapSerializer,
Int16: Int16Serializer,
Int32: Int32Serializer,
Int64: Int64Serializer,
Int8: Int8Serializer,
Memo: EncryptedMemoSerializer,
Object: ObjectSerializer,
Operation: OperationSerializer,
Optional: OptionalSerializer,
PublicKey: PublicKeySerializer,
StaticVariant: StaticVariantSerializer,
String: StringSerializer,
Transaction: TransactionSerializer,
UInt16: UInt16Serializer,
UInt32: UInt32Serializer,
UInt64: UInt64Serializer,
UInt8: UInt8Serializer,
Void: VoidSerializer
};