@taquito/utils
Version:
converts michelson data and types into convenient JS/TS objects
954 lines (945 loc) • 32 kB
JavaScript
import { Buffer } from 'buffer';
import { verify } from '@stablelib/ed25519';
import { hash } from '@stablelib/blake2b';
import blake from 'blakejs';
import bs58check from 'bs58check';
import { InvalidMessageError, InvalidPublicKeyError, InvalidSignatureError, ParameterValidationError, UnsupportedActionError, InvalidHexStringError } from '@taquito/core';
export { DeprecationError, InvalidAddressError, InvalidBlockHashError, InvalidChainIdError, InvalidContractAddressError, InvalidHexStringError, InvalidKeyError, InvalidKeyHashError, InvalidMessageError, InvalidOperationHashError, InvalidOperationKindError, InvalidPublicKeyError, InvalidSignatureError, ProhibitedActionError } from '@taquito/core';
import BigNumber from 'bignumber.js';
import elliptic from 'elliptic';
import toBuffer from 'typedarray-to-buffer';
// ref https://gitlab.com/tezos/tezos/-/blob/master/src/lib_crypto/base58.ml
var Prefix;
(function (Prefix) {
Prefix["TZ1"] = "tz1";
Prefix["TZ2"] = "tz2";
Prefix["TZ3"] = "tz3";
Prefix["TZ4"] = "tz4";
Prefix["KT"] = "KT";
Prefix["KT1"] = "KT1";
Prefix["EDSK"] = "edsk";
Prefix["EDSK2"] = "edsk2";
Prefix["SPSK"] = "spsk";
Prefix["P2SK"] = "p2sk";
Prefix["BLSK"] = "BLsk";
Prefix["EDPK"] = "edpk";
Prefix["SPPK"] = "sppk";
Prefix["P2PK"] = "p2pk";
Prefix["BLPK"] = "BLpk";
Prefix["EDESK"] = "edesk";
Prefix["SPESK"] = "spesk";
Prefix["P2ESK"] = "p2esk";
Prefix["BLESK"] = "BLesk";
Prefix["EDSIG"] = "edsig";
Prefix["SPSIG"] = "spsig";
Prefix["P2SIG"] = "p2sig";
Prefix["BLSIG"] = "BLsig";
Prefix["SIG"] = "sig";
Prefix["NET"] = "Net";
Prefix["NCE"] = "nce";
Prefix["B"] = "B";
Prefix["O"] = "o";
Prefix["LO"] = "Lo";
Prefix["LLO"] = "LLo";
Prefix["P"] = "P";
Prefix["CO"] = "Co";
Prefix["ID"] = "id";
Prefix["EXPR"] = "expr";
Prefix["TZ"] = "TZ";
Prefix["VH"] = "vh";
Prefix["SASK"] = "sask";
Prefix["ZET1"] = "zet1";
Prefix["SR1"] = "sr1";
Prefix["SRC1"] = "src1";
Prefix["SH"] = "sh";
})(Prefix || (Prefix = {}));
const prefix = {
[Prefix.TZ1]: new Uint8Array([6, 161, 159]),
[Prefix.TZ2]: new Uint8Array([6, 161, 161]),
[Prefix.TZ3]: new Uint8Array([6, 161, 164]),
[Prefix.TZ4]: new Uint8Array([6, 161, 166]),
[Prefix.KT]: new Uint8Array([2, 90, 121]),
[Prefix.KT1]: new Uint8Array([2, 90, 121]),
[Prefix.EDSK]: new Uint8Array([43, 246, 78, 7]),
[Prefix.EDSK2]: new Uint8Array([13, 15, 58, 7]),
[Prefix.SPSK]: new Uint8Array([17, 162, 224, 201]),
[Prefix.P2SK]: new Uint8Array([16, 81, 238, 189]),
[Prefix.BLSK]: new Uint8Array([3, 150, 192, 40]),
[Prefix.EDPK]: new Uint8Array([13, 15, 37, 217]),
[Prefix.SPPK]: new Uint8Array([3, 254, 226, 86]),
[Prefix.P2PK]: new Uint8Array([3, 178, 139, 127]),
[Prefix.BLPK]: new Uint8Array([6, 149, 135, 204]),
[Prefix.EDESK]: new Uint8Array([7, 90, 60, 179, 41]),
[Prefix.SPESK]: new Uint8Array([0x09, 0xed, 0xf1, 0xae, 0x96]),
[Prefix.P2ESK]: new Uint8Array([0x09, 0x30, 0x39, 0x73, 0xab]),
[Prefix.BLESK]: new Uint8Array([2, 5, 30, 53, 25]),
[Prefix.EDSIG]: new Uint8Array([9, 245, 205, 134, 18]),
[Prefix.SPSIG]: new Uint8Array([13, 115, 101, 19, 63]),
[Prefix.P2SIG]: new Uint8Array([54, 240, 44, 52]),
[Prefix.BLSIG]: new Uint8Array([40, 171, 64, 207]),
[Prefix.SIG]: new Uint8Array([4, 130, 43]),
[Prefix.NET]: new Uint8Array([87, 82, 0]),
[Prefix.NCE]: new Uint8Array([69, 220, 169]),
[Prefix.B]: new Uint8Array([1, 52]),
[Prefix.O]: new Uint8Array([5, 116]),
[Prefix.LO]: new Uint8Array([133, 233]),
[Prefix.LLO]: new Uint8Array([29, 159, 109]),
[Prefix.P]: new Uint8Array([2, 170]),
[Prefix.CO]: new Uint8Array([79, 179]),
[Prefix.ID]: new Uint8Array([153, 103]),
[Prefix.EXPR]: new Uint8Array([13, 44, 64, 27]),
// Legacy prefix
[Prefix.TZ]: new Uint8Array([2, 90, 121]),
[Prefix.VH]: new Uint8Array([1, 106, 242]),
[Prefix.SASK]: new Uint8Array([11, 237, 20, 92]),
[Prefix.ZET1]: new Uint8Array([18, 71, 40, 223]),
[Prefix.SR1]: new Uint8Array([6, 124, 117]),
[Prefix.SRC1]: new Uint8Array([17, 165, 134, 138]),
[Prefix.SH]: new Uint8Array([2, 116, 180]),
};
const prefixLength = {
[Prefix.TZ1]: 20,
[Prefix.TZ2]: 20,
[Prefix.TZ3]: 20,
[Prefix.TZ4]: 20,
[Prefix.KT]: 20,
[Prefix.KT1]: 20,
[Prefix.EDPK]: 32,
[Prefix.SPPK]: 33,
[Prefix.P2PK]: 33,
[Prefix.BLPK]: 48,
[Prefix.EDSIG]: 64,
[Prefix.SPSIG]: 64,
[Prefix.P2SIG]: 64,
[Prefix.BLSIG]: 96,
[Prefix.SIG]: 64,
[Prefix.NET]: 4,
[Prefix.B]: 32,
[Prefix.P]: 32,
[Prefix.O]: 32,
[Prefix.VH]: 32,
[Prefix.SASK]: 169,
[Prefix.ZET1]: 43,
[Prefix.SR1]: 20,
[Prefix.SRC1]: 32,
[Prefix.SH]: 48,
};
/**
* @description Verify signature of a payload
*
* @param messageBytes The forged message including the magic byte (11 for block,
* 12 for preattestation, 13 for attestation, 3 for generic, 5 for the PACK format of michelson)
* @param publicKey The public key to verify the signature against
* @param signature The signature to verify
* @returns A boolean indicating if the signature matches
* @throws {@link InvalidPublicKeyError} | {@link InvalidSignatureError} | {@link InvalidMessageError}
* @example
* ```
* const message = '03d0c10e3ed11d7c6e3357f6ef335bab9e8f2bd54d0ce20c482e241191a6e4b8ce6c01be917311d9ac46959750e405d57e268e2ed9e174a80794fbd504e12a4a000141eb3781afed2f69679ff2bbe1c5375950b0e40d00ff000000005e05050505050507070100000024747a32526773486e74516b72794670707352466261313652546656503539684b72654a4d07070100000024747a315a6672455263414c42776d4171776f6e525859565142445439426a4e6a42484a750001';
* const pk = 'sppk7c7hkPj47yjYFEHX85q46sFJGw6RBrqoVSHwAJAT4e14KJwzoey';
* const sig = 'spsig1cdLkp1RLgUHAp13aRFkZ6MQDPp7xCnjAExGL3MBSdMDmT6JgQSX8cufyDgJRM3sinFtiCzLbsyP6d365EHoNevxhT47nx'
*
* const response = verifySignature(message, pk, sig);
* ```
*
*/
function verifySignature(messageBytes, publicKey, signature, watermark) {
const pkPrefix = validatePkAndExtractPrefix(publicKey);
const sigPrefix = validateSigAndExtractPrefix(signature);
const decodedPublicKey = b58cdecode(publicKey, prefix[pkPrefix]);
const decodedSig = b58cdecode(signature, prefix[sigPrefix]);
let messageBuf = hex2buf(validateMessageNotEmpty(messageBytes));
if (typeof watermark !== 'undefined') {
messageBuf = mergebuf(watermark, messageBuf);
}
const bytesHash = hash(messageBuf, 32);
if (pkPrefix === Prefix.EDPK) {
return verifyEdSignature(decodedSig, bytesHash, decodedPublicKey);
}
else if (pkPrefix === Prefix.SPPK) {
return verifySpSignature(decodedSig, bytesHash, decodedPublicKey);
}
else if (pkPrefix === Prefix.P2PK) {
return verifyP2Signature(decodedSig, bytesHash, decodedPublicKey);
}
else {
return false;
}
}
function validateMessageNotEmpty(message) {
if (message === '') {
throw new InvalidMessageError(message, `can't be empty`);
}
return message;
}
function validatePkAndExtractPrefix(publicKey) {
if (publicKey === '') {
throw new InvalidPublicKeyError(publicKey, `can't be empty`);
}
const pkPrefix = publicKey.substring(0, 4);
const publicKeyValidation = validatePublicKey(publicKey);
if (publicKeyValidation !== ValidationResult.VALID) {
throw new InvalidPublicKeyError(publicKey, invalidDetail(publicKeyValidation));
}
return pkPrefix;
}
function validateSigAndExtractPrefix(signature) {
const signaturePrefix = signature.startsWith('sig')
? signature.substring(0, 3)
: signature.substring(0, 5);
const validation = validateSignature(signature);
if (validation !== ValidationResult.VALID) {
throw new InvalidSignatureError(signature, invalidDetail(validation));
}
return signaturePrefix;
}
function verifyEdSignature(decodedSig, bytesHash, decodedPublicKey) {
try {
return verify(decodedPublicKey, bytesHash, decodedSig);
}
catch (e) {
return false;
}
}
function verifySpSignature(decodedSig, bytesHash, decodedPublicKey) {
const key = new elliptic.ec('secp256k1').keyFromPublic(decodedPublicKey);
return verifySpOrP2Sig(decodedSig, bytesHash, key);
}
function verifyP2Signature(decodedSig, bytesHash, decodedPublicKey) {
const key = new elliptic.ec('p256').keyFromPublic(decodedPublicKey);
return verifySpOrP2Sig(decodedSig, bytesHash, key);
}
function verifySpOrP2Sig(decodedSig, bytesHash, key) {
const hexSig = buf2hex(toBuffer(decodedSig));
const match = hexSig.match(/([a-f\d]{64})/gi);
if (match) {
try {
const [r, s] = match;
return key.verify(bytesHash, { r, s });
}
catch (e) {
return false;
}
}
return false;
}
/**
* @category Error
* @description Error that indicates invalid protocol hash being passed or used
*/
class InvalidProtocolHashError extends ParameterValidationError {
constructor(protocolHash, errorDetails) {
super();
this.protocolHash = protocolHash;
this.errorDetails = errorDetails;
this.name = 'InvalidProtocolHashError';
this.name = 'InvalidProtocolHashError';
this.message = `The protocol hash '${protocolHash}' is invalid`;
errorDetails ? (this.message += `: ${errorDetails}`) : null;
}
}
/**
* @category Error
* @description Error that indicates unable to convert data type from one to another
*/
class ValueConversionError extends UnsupportedActionError {
constructor(value, desiredType) {
super();
this.value = value;
this.desiredType = desiredType;
this.name = 'ValueConversionError';
this.message = `Unable to convert ${value} to a ${desiredType}`;
}
}
var ValidationResult;
(function (ValidationResult) {
ValidationResult[ValidationResult["NO_PREFIX_MATCHED"] = 0] = "NO_PREFIX_MATCHED";
ValidationResult[ValidationResult["INVALID_CHECKSUM"] = 1] = "INVALID_CHECKSUM";
ValidationResult[ValidationResult["INVALID_LENGTH"] = 2] = "INVALID_LENGTH";
ValidationResult[ValidationResult["VALID"] = 3] = "VALID";
})(ValidationResult || (ValidationResult = {}));
function isValidPrefix(value) {
if (typeof value !== 'string') {
return false;
}
return value in prefix;
}
/**
* @description This function is called by the validation functions ([[validateAddress]], [[validateChain]], [[validateContractAddress]], [[validateKeyHash]], [[validateSignature]], [[validatePublicKey]]).
* Verify if the value has the right prefix or return `NO_PREFIX_MATCHED`,
* decode the value using base58 and return `INVALID_CHECKSUM` if it fails,
* check if the length of the value matches the prefix type or return `INVALID_LENGTH`.
* If all checks pass, return `VALID`.
*
* @param value Value to validate
* @param prefixes prefix the value should have
*/
function validatePrefixedValue(value, prefixes) {
const match = new RegExp(`^(${prefixes.join('|')})`).exec(value);
if (!match || match.length === 0) {
return ValidationResult.NO_PREFIX_MATCHED;
}
const prefixKey = match[0];
if (!isValidPrefix(prefixKey)) {
return ValidationResult.NO_PREFIX_MATCHED;
}
// Check whether annotation exist before starting validation
if (value.includes('%')) {
value = value.split('%')[0];
}
const kt1Regex = /^(KT1\w{33})$/;
if (!kt1Regex.test(value) && prefixKey === 'KT1') {
return ValidationResult.INVALID_CHECKSUM;
}
// decodeUnsafe return undefined if decoding fail
let decoded = bs58check.decodeUnsafe(value);
if (!decoded) {
return ValidationResult.INVALID_CHECKSUM;
}
decoded = decoded.slice(prefix[prefixKey].length);
if (decoded.length !== prefixLength[prefixKey]) {
return ValidationResult.INVALID_LENGTH;
}
return ValidationResult.VALID;
}
const implicitPrefix = [Prefix.TZ1, Prefix.TZ2, Prefix.TZ3, Prefix.TZ4];
const contractPrefix = [Prefix.KT1];
const signaturePrefix = [Prefix.EDSIG, Prefix.P2SIG, Prefix.SPSIG, Prefix.SIG];
const pkPrefix = [Prefix.EDPK, Prefix.SPPK, Prefix.P2PK, Prefix.BLPK];
const operationPrefix = [Prefix.O];
const protocolPrefix = [Prefix.P];
const blockPrefix = [Prefix.B];
const smartRollupPrefix = [Prefix.SR1];
/**
* @description Used to check if an address or a contract address is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateAddress } from '@taquito/utils';
* const pkh = 'tz1L9r8mWmRPndRhuvMCWESLGSVeFzQ9NAWx'
* const validation = validateAddress(pkh)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateAddress(value) {
return validatePrefixedValue(value, [...implicitPrefix, ...contractPrefix, ...smartRollupPrefix]);
}
/**
* @description Used to check if a chain id is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateChain } from '@taquito/utils';
* const chainId = 'NetXdQprcVkpaWU'
* const validation = validateChain(chainId)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateChain(value) {
return validatePrefixedValue(value, [Prefix.NET]);
}
/**
* @description Used to check if a contract address is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateContractAddress } from '@taquito/utils';
* const contractAddress = 'KT1JVErLYTgtY8uGGZ4mso2npTSxqVLDRVbC'
* const validation = validateContractAddress(contractAddress)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateContractAddress(value) {
return validatePrefixedValue(value, contractPrefix);
}
/**
* @description Used to check if a key hash is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateKeyHash } from '@taquito/utils';
* const keyHashWithoutPrefix = '1L9r8mWmRPndRhuvMCWESLGSVeFzQ9NAWx'
* const validation = validateKeyHash(keyHashWithoutPrefix)
* console.log(validation)
* // This example return 0 which correspond to NO_PREFIX_MATCHED
* ```
*/
function validateKeyHash(value) {
return validatePrefixedValue(value, implicitPrefix);
}
/**
* @description Used to check if a signature is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateSignature } from '@taquito/utils';
* const signature = 'edsigtkpiSSschcaCt9pUVrpNPf7TTcgvgDEDD6NCEHMy8NNQJCGnMfLZzYoQj74yLjo9wx6MPVV29CvVzgi7qEcEUok3k7AuMg'
* const validation = validateSignature(signature)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateSignature(value) {
return validatePrefixedValue(value, signaturePrefix);
}
/**
* @description Used to check if a public key is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validatePublicKey } from '@taquito/utils';
* const publicKey = 'edpkvS5QFv7KRGfa3b87gg9DBpxSm3NpSwnjhUjNBQrRUUR66F7C9g'
* const validation = validatePublicKey(publicKey)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validatePublicKey(value) {
return validatePrefixedValue(value, pkPrefix);
}
/**
* @description Used to check if an operation hash is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateOperation } from '@taquito/utils';
* const operationHash = 'oo6JPEAy8VuMRGaFuMmLNFFGdJgiaKfnmT1CpHJfKP3Ye5ZahiP'
* const validation = validateOperation(operationHash)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateOperation(value) {
return validatePrefixedValue(value, operationPrefix);
}
/**
* @description Used to check if a protocol hash is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateProtocol } from '@taquito/utils';
* const protocolHash = 'PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx'
* const validation = validateProtocol(protocolHash)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateProtocol(value) {
return validatePrefixedValue(value, protocolPrefix);
}
/**
* @description Used to check if a block hash is valid.
*
* @returns
* 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
* @example
* ```
* import { validateBlock } from '@taquito/utils';
* const blockHash = 'PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx'
* const validation = validateBlock(blockHash)
* console.log(validation)
* // This example return 3 which correspond to VALID
* ```
*/
function validateBlock(value) {
return validatePrefixedValue(value, blockPrefix);
}
/**
* @description Used to check if a spending key is valid.
* @returns 0 (NO_PREFIX_MATCHED), 1 (INVALID_CHECKSUM), 2 (INVALID_LENGTH) or 3 (VALID).
*
*/
function validateSpendingKey(value) {
return validatePrefixedValue(value, [Prefix.SASK]);
}
function invalidDetail(validation) {
switch (validation) {
case ValidationResult.NO_PREFIX_MATCHED:
return 'with unsupported prefix';
case ValidationResult.INVALID_CHECKSUM:
return 'failed checksum';
case ValidationResult.INVALID_LENGTH:
return 'with incorrect length';
default:
return '';
}
}
function validateSmartRollupAddress(value) {
return validatePrefixedValue(value, [...smartRollupPrefix]);
}
// IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT OR CHECKIN!
const VERSION = {
"commitHash": "6a2c52b9e48b299dfc856149c1fa3388e77180ad",
"version": "22.0.0"
};
const TZ_DECIMALS = 6;
const MTZ_DECIMALS = 3;
function getDecimal(format) {
switch (format) {
case 'tz':
return TZ_DECIMALS;
case 'mtz':
return MTZ_DECIMALS;
case 'mutez':
default:
return 0;
}
}
function format(from = 'mutez', to = 'mutez', amount) {
const bigNum = new BigNumber(amount);
if (bigNum.isNaN()) {
return amount;
}
return bigNum
.multipliedBy(Math.pow(10, getDecimal(from)))
.dividedBy(Math.pow(10, getDecimal(to)));
}
/**
* @packageDocumentation
* @module @taquito/utils
*/
/*
* Some code in this file is originally from sotez and eztz
* Copyright (c) 2018 Andrew Kishino
* Copyright (c) 2017 Stephen Andrews
*/
/**
*
* @description Hash a string using the BLAKE2b algorithm, base58 encode the hash obtained and appends the prefix 'expr' to it
*
* @param value Value in hex
*/
function encodeExpr(value) {
const blakeHash = blake.blake2b(hex2buf(value), undefined, 32);
return b58cencode(blakeHash, prefix['expr']);
}
/**
*
* @description Return the operation hash of a signed operation
* @param value Value in hex of a signed operation
*/
function encodeOpHash(value) {
const blakeHash = blake.blake2b(hex2buf(value), undefined, 32);
return b58cencode(blakeHash, prefix.o);
}
/**
*
* @description Base58 encode a string or a Uint8Array and append a prefix to it
*
* @param value Value to base58 encode
* @param prefix prefix to append to the encoded string
*/
function b58cencode(value, prefix) {
const payloadAr = typeof value === 'string' ? Uint8Array.from(Buffer.from(value, 'hex')) : value;
const n = new Uint8Array(prefix.length + payloadAr.length);
n.set(prefix);
n.set(payloadAr, prefix.length);
return bs58check.encode(Buffer.from(n.buffer));
}
/**
*
* @description Base58 decode a string and remove the prefix from it
*
* @param value Value to base58 decode
* @param prefix prefix to remove from the decoded string
*/
const b58cdecode = (enc, prefixArg) => bs58check.decode(enc).slice(prefixArg.length);
/**
*
* @description Base58 decode a string with predefined prefix
*
* @param value Value to base58 decode
*/
function b58decode(payload) {
const buf = bs58check.decode(payload);
const prefixMap = {
[prefix.tz1.toString()]: '0000',
[prefix.tz2.toString()]: '0001',
[prefix.tz3.toString()]: '0002',
[prefix.tz4.toString()]: '0003',
};
const pref = prefixMap[new Uint8Array(buf.slice(0, 3)).toString()];
if (pref) {
// tz addresses
const hex = buf2hex(buf.slice(3));
return pref + hex;
}
else {
// other (kt addresses)
return '01' + buf2hex(buf.slice(3, 42)) + '00';
}
}
/**
*
* @description b58 decode a string without predefined prefix
* @param value
* @returns string of bytes
* @deprecated use b58decode instead
*/
function b58decodeL2Address(payload) {
const buf = bs58check.decode(payload);
// tz4 address currently
return buf2hex(buf.slice(3, 42));
}
/**
*
* @description Base58 encode an address using predefined prefix
*
* @param value Address to base58 encode (tz1, tz2, tz3 or KT1)
* @deprecated use encodeAddress instead, same functionality with a more descriptive name
*/
function encodePubKey(value) {
if (value.substring(0, 2) === '00') {
const pref = {
'0000': prefix.tz1,
'0001': prefix.tz2,
'0002': prefix.tz3,
'0003': prefix.tz4,
};
return b58cencode(value.substring(4), pref[value.substring(0, 4)]);
}
return b58cencode(value.substring(2, 42), prefix.KT);
}
/**
*
* @description Base58 encode an address using predefined prefix (tz1, tz2, tz3, or KT1 without annotation)
*
* @param value Address to base58 encode (tz1, tz2, tz3 or KT1). Supports value with or without '0x' prefix
*/
function encodeAddress(value) {
if (value.substring(0, 2) === '0x') {
value = value.slice(2);
}
if (value.substring(0, 2) === '00') {
const pref = {
'0000': prefix.tz1,
'0001': prefix.tz2,
'0002': prefix.tz3,
'0003': prefix.tz4,
};
return b58cencode(value.substring(4), pref[value.substring(0, 4)]);
}
return b58cencode(value.substring(2, 42), prefix.KT);
}
/**
*
* @description Base58 encode an address without predefined prefix
* @param value Address to base58 encode (tz4) hex dec
* @returns return address
* @deprecated use encodeAddress instead
*/
function encodeL2Address(value) {
return b58cencode(value, prefix.tz4);
}
/**
*
* @description Base58 encode a key according to its prefix
*
* @param value Key to base58 encode
*/
function encodeKey(value) {
if (value[0] === '0') {
const pref = {
'00': new Uint8Array([13, 15, 37, 217]),
'01': new Uint8Array([3, 254, 226, 86]),
'02': new Uint8Array([3, 178, 139, 127]),
};
return b58cencode(value.substring(2), pref[value.substring(0, 2)]);
}
}
/**
*
* @description Base58 encode a key hash according to its prefix
*
* @param value Key hash to base58 encode
*/
function encodeKeyHash(value) {
if (value[0] === '0') {
const pref = {
'00': new Uint8Array([6, 161, 159]),
'01': new Uint8Array([6, 161, 161]),
'02': new Uint8Array([6, 161, 164]),
'03': new Uint8Array([6, 161, 167]),
};
return b58cencode(value.substring(2), pref[value.substring(0, 2)]);
}
}
/**
*
* @description Convert an hex string to a Uint8Array
*
* @param hex Hex string to convert
* @throws {@link ValueConversionError}
*/
const hex2buf = (hex) => {
if (hex.length % 2 !== 0) {
throw new InvalidHexStringError(hex, `: Expecting even number of characters`);
}
const hexDigits = stripHexPrefix(hex);
if (!hexDigits.match(/^([\da-f]{2})*$/gi)) {
throw new InvalidHexStringError(hex, `: Only characters 0-9, a-f and A-F are expected. Optionally, it can be prefixed with '0x'`);
}
const out = new Uint8Array(hexDigits.length / 2);
let j = 0;
for (let i = 0; i < hexDigits.length; i += 2) {
const v = parseInt(hexDigits.slice(i, i + 2), 16);
if (Number.isNaN(v)) {
throw new ValueConversionError(hex, 'Uint8Array');
}
out[j++] = v;
}
return out;
};
/**
*
* @description Merge 2 buffers together
*
* @param b1 First buffer
* @param b2 Second buffer
*/
const mergebuf = (b1, b2) => {
const r = new Uint8Array(b1.length + b2.length);
r.set(b1);
r.set(b2, b1.length);
return r;
};
/**
*
* @description Flatten a michelson json representation to an array
*
* @param s michelson json
*/
const mic2arr = function me2(s) {
let ret = [];
if (Object.prototype.hasOwnProperty.call(s, 'prim')) {
if (s.prim === 'Pair') {
ret.push(me2(s.args[0]));
ret = ret.concat(me2(s.args[1]));
}
else if (s.prim === 'Elt') {
ret = {
key: me2(s.args[0]),
val: me2(s.args[1]),
};
}
else if (s.prim === 'True') {
ret = true;
}
else if (s.prim === 'False') {
ret = false;
}
}
else if (Array.isArray(s)) {
const sc = s.length;
for (let i = 0; i < sc; i++) {
const n = me2(s[i]);
if (typeof n.key !== 'undefined') {
if (Array.isArray(ret)) {
ret = {
keys: [],
vals: [],
};
}
ret.keys.push(n.key);
ret.vals.push(n.val);
}
else {
ret.push(n);
}
}
}
else if (Object.prototype.hasOwnProperty.call(s, 'string')) {
ret = s.string;
}
else if (Object.prototype.hasOwnProperty.call(s, 'int')) {
ret = parseInt(s.int, 10);
}
else {
ret = s;
}
return ret;
};
/**
*
* @description Convert a Uint8Array to an hex string
*
* @param buffer Uint8Array to convert
*/
const buf2hex = (buffer) => {
const hexParts = [];
buffer.forEach((byte) => {
const hex = byte.toString(16);
const paddedHex = `00${hex}`.slice(-2);
hexParts.push(paddedHex);
});
return hexParts.join('');
};
/**
*
* @description Gets Tezos address (PKH) from Public Key
*
* @param publicKey Public Key
* @returns A string of the Tezos address (PKH) that was derived from the given Public Key
*/
const getPkhfromPk = (publicKey) => {
let encodingPrefix;
let prefixLen;
const keyPrefix = validatePkAndExtractPrefix(publicKey);
const decoded = b58cdecode(publicKey, prefix[keyPrefix]);
switch (keyPrefix) {
case Prefix.EDPK:
encodingPrefix = prefix[Prefix.TZ1];
prefixLen = prefixLength[Prefix.TZ1];
break;
case Prefix.SPPK:
encodingPrefix = prefix[Prefix.TZ2];
prefixLen = prefixLength[Prefix.TZ2];
break;
case Prefix.P2PK:
encodingPrefix = prefix[Prefix.TZ3];
prefixLen = prefixLength[Prefix.TZ3];
break;
case Prefix.BLPK:
encodingPrefix = prefix[Prefix.TZ4];
prefixLen = prefixLength[Prefix.TZ4];
}
const hashed = hash(decoded, prefixLen);
const result = b58cencode(hashed, encodingPrefix);
return result;
};
/**
*
* @description Convert a string to bytes
*
* @param str String to convert
* @deprecated use stringToBytes instead, same functionality with a more descriptive name
*/
function char2Bytes(str) {
return Buffer.from(str, 'utf8').toString('hex');
}
/**
*
* @description Convert a string to a byte string representation
*
* @param str String to convert
*/
function stringToBytes(str) {
return Buffer.from(str, 'utf8').toString('hex');
}
/**
*
* @description Convert bytes to a string
*
* @param str Bytes to convert
* @deprecated use hexStringToBytes instead, same functionality with a more descriptive name
*/
function bytes2Char(hex) {
return Buffer.from(hex2buf(hex)).toString('utf8');
}
/**
*
* @description Convert byte string representation to string
*
* @param str byte string to convert
*/
function bytesToString(hex) {
return Buffer.from(hex2buf(hex)).toString('utf8');
}
/**
*
* @description Convert hex string/UintArray/Buffer to bytes
*
* @param hex String value to convert to bytes
*/
function hex2Bytes(hex) {
const hexDigits = stripHexPrefix(hex);
if (!hexDigits.match(/^(0x)?([\da-f]{2})*$/gi)) {
throw new InvalidHexStringError(hex, `: Expecting even number of characters: 0-9, a-z, A-Z, optionally prefixed with 0x`);
}
return Buffer.from(hexDigits, 'hex');
}
/**
*
* @description Converts a number or Bignumber to hexadecimal string
*
* @param val The value that will be converted to a hexadecimal string value
*/
function toHexBuf(val, bitLength = 8) {
return Buffer.from(num2PaddedHex(val, bitLength), 'hex');
}
function numToHexBuffer(val, bitLength = 8) {
return Buffer.from(num2PaddedHex(val, bitLength), 'hex');
}
/**
*
* @description Converts a number or BigNumber to a padded hexadecimal string
* @param val The value that will be converted into a padded hexadecimal string value
* @param bitLength The length of bits
*
*/
function num2PaddedHex(val, bitLength = 8) {
if (new BigNumber(val).isPositive()) {
const nibbleLength = Math.ceil(bitLength / 4);
const hex = val.toString(16);
// check whether nibble (4 bits) length is higher or lower than the current hex string length
let targetLength = hex.length >= nibbleLength ? hex.length : nibbleLength;
// make sure the hex string target length is even
targetLength = targetLength % 2 == 0 ? targetLength : targetLength + 1;
return padHexWithZero(hex, targetLength);
}
else {
const twosCompliment = new BigNumber(2)
.pow(bitLength)
.minus(new BigNumber(val).abs());
return twosCompliment.toString(16);
}
}
function padHexWithZero(hex, targetLength) {
const padString = '0';
if (hex.length >= targetLength) {
return hex;
}
else {
const padLength = targetLength - hex.length;
return padString.repeat(padLength) + hex;
}
}
/**
*
* @description Strips the first 2 characters of a hex string (0x)
*
* @param hex string to strip prefix from
*/
function stripHexPrefix(hex) {
return hex.startsWith('0x') ? hex.slice(2) : hex;
}
export { InvalidProtocolHashError, Prefix, VERSION, ValidationResult, ValueConversionError, b58cdecode, b58cencode, b58decode, b58decodeL2Address, buf2hex, bytes2Char, bytesToString, char2Bytes, encodeAddress, encodeExpr, encodeKey, encodeKeyHash, encodeL2Address, encodeOpHash, encodePubKey, format, getPkhfromPk, hex2Bytes, hex2buf, invalidDetail, isValidPrefix, mergebuf, mic2arr, num2PaddedHex, numToHexBuffer, prefix, prefixLength, stringToBytes, stripHexPrefix, toHexBuf, validateAddress, validateBlock, validateChain, validateContractAddress, validateKeyHash, validateOperation, validatePkAndExtractPrefix, validateProtocol, validatePublicKey, validateSignature, validateSmartRollupAddress, validateSpendingKey, verifySignature };
//# sourceMappingURL=taquito-utils.es6.js.map