UNPKG

@aeternity/aepp-sdk

Version:

SDK for the æternity blockchain

106 lines (101 loc) 4.5 kB
import { Buffer as _Buffer } from "buffer"; import bs58 from 'bs58'; // js extension is required for mjs build, not importing the whole package to reduce bundle size // eslint-disable-next-line import/extensions import Sha256 from 'sha.js/sha256.js'; import { DecodeError, ArgumentError, InvalidChecksumError, PayloadLengthError } from './errors.js'; import { concatBuffers, isKeyOfObject } from './other.js'; import * as Encoded from './encoder-types.js'; import { Encoding } from './encoder-types.js'; export { Encoded, Encoding }; /** * Calculate SHA256 hash of `input` * @param input - Data to hash * @returns Hash */ export function sha256hash(input) { return new Sha256().update(input).digest(); } /** * @see {@link https://github.com/aeternity/aeserialization/blob/eb68fe331bd476910394966b7f5ede7a74d37e35/src/aeser_api_encoder.erl#L177-L202} */ const base64Types = [Encoding.ContractBytearray, Encoding.ContractStoreKey, Encoding.ContractStoreValue, Encoding.Transaction, Encoding.OracleQuery, Encoding.OracleResponse, Encoding.State, Encoding.Poi, Encoding.StateTrees, Encoding.CallStateTree, Encoding.Bytearray]; const base58Types = [Encoding.KeyBlockHash, Encoding.MicroBlockHash, Encoding.BlockPofHash, Encoding.BlockTxHash, Encoding.BlockStateHash, Encoding.Channel, Encoding.ContractAddress, Encoding.TxHash, Encoding.OracleAddress, Encoding.OracleQueryId, Encoding.AccountAddress, Encoding.AccountSecretKey, Encoding.Signature, Encoding.Commitment, Encoding.PeerPubkey, Encoding.Name]; /** * @see {@link https://github.com/aeternity/aeserialization/blob/eb68fe331bd476910394966b7f5ede7a74d37e35/src/aeser_api_encoder.erl#L261-L286} */ const byteSizeForType = { [Encoding.KeyBlockHash]: 32, [Encoding.MicroBlockHash]: 32, [Encoding.BlockPofHash]: 32, [Encoding.BlockTxHash]: 32, [Encoding.BlockStateHash]: 32, [Encoding.Channel]: 32, [Encoding.ContractAddress]: 32, [Encoding.TxHash]: 32, [Encoding.OracleAddress]: 32, [Encoding.OracleQueryId]: 32, [Encoding.AccountAddress]: 32, [Encoding.AccountSecretKey]: 32, [Encoding.Signature]: 64, [Encoding.Commitment]: 32, [Encoding.PeerPubkey]: 32, [Encoding.State]: 32 }; function ensureValidLength(data, type) { if (!isKeyOfObject(type, byteSizeForType)) return; const reqLen = byteSizeForType[type]; if (reqLen == null || data.length === reqLen) return; throw new PayloadLengthError(`Payload should be ${reqLen} bytes, got ${data.length} instead`); } const getChecksum = payload => sha256hash(sha256hash(payload)).slice(0, 4); const addChecksum = payload => concatBuffers([payload, getChecksum(payload)]); function getPayload(buffer) { const payload = buffer.slice(0, -4); if (!getChecksum(payload).equals(buffer.slice(-4))) throw new InvalidChecksumError(); return payload; } const base64 = { encode: buffer => addChecksum(buffer).toString('base64'), decode: string => getPayload(_Buffer.from(string, 'base64')) }; const base58 = { encode: buffer => bs58.encode(addChecksum(buffer)), decode: string => getPayload(_Buffer.from(bs58.decode(string))) }; const parseType = maybeType => { const base64Type = base64Types.find(t => t === maybeType); if (base64Type != null) return [base64Type, base64]; const base58Type = base58Types.find(t => t === maybeType); if (base58Type != null) return [base58Type, base58]; throw new ArgumentError('prefix', `one of ${[...base58Types, ...base64Types].join(', ')}`, maybeType); }; /** * Decode data using the default encoding/decoding algorithm * @param data - An Base58/64check encoded and prefixed string * (ex tx_..., sg_..., ak_....) * @returns Decoded data * @category utils */ export function decode(data) { const [prefix, encodedPayload, extra] = data.split('_'); if (encodedPayload == null) throw new DecodeError(`Encoded string missing payload: ${data}`); if (extra != null) throw new DecodeError(`Encoded string have extra parts: ${data}`); const [type, encoder] = parseType(prefix); const payload = encoder.decode(encodedPayload); ensureValidLength(payload, type); return payload; } /** * Encode data using the default encoding/decoding algorithm * @param data - An decoded data * @param type - Prefix of Transaction * @returns Encoded string Base58check or Base64check data * @category utils */ export function encode(data, type) { const [, encoder] = parseType(type); ensureValidLength(data, type); return `${type}_${encoder.encode(data)}`; } //# sourceMappingURL=encoder.js.map