UNPKG

@taquito/taquito

Version:

High level functionality that builds upon the other packages in the Tezos Typescript Library Suite.

1,238 lines (1,217 loc) 270 kB
import { OpKind, RpcClient } from '@taquito/rpc'; export { OpKind } from '@taquito/rpc'; import { HttpResponseError, STATUS_CODE } from '@taquito/http-utils'; import { Observable, ReplaySubject, BehaviorSubject, throwError, defer, range, of, EMPTY, combineLatest, from, concat, Subject, NEVER, timer } from 'rxjs'; import { switchMap, timeoutWith, concatMap, endWith, tap, shareReplay, map, filter, first, catchError, publishReplay, refCount, distinctUntilChanged, takeWhile, startWith, mergeMap, takeUntil, retry, pluck, distinctUntilKeyChanged, publish } from 'rxjs/operators'; import { Schema, ParameterSchema, ViewSchema, MichelsonMap } from '@taquito/michelson-encoder'; export { MichelsonMap, UnitValue } from '@taquito/michelson-encoder'; import { format, validateOperation, ValidationResult, InvalidOperationKindError, validateAddress, invalidErrorDetail, validateContractAddress, validateChain, DeprecationError as DeprecationError$1, validateKeyHash, InvalidKeyHashError as InvalidKeyHashError$1, encodeExpr } from '@taquito/utils'; import BigNumber, { BigNumber as BigNumber$1 } from 'bignumber.js'; import { InvalidOperationHashError, InvalidAddressError, InvalidOperationKindError as InvalidOperationKindError$1, InvalidContractAddressError, InvalidViewParameterError, DeprecationError, InvalidChainIdError, InvalidKeyHashError } from '@taquito/core'; import { Parser, packDataBytes } from '@taquito/michel-codec'; import { LocalForger } from '@taquito/local-forging'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } function formatErrorMessage(error, stringToReplace) { const body = JSON.parse(error.body); if (body[0] && body[0].kind && body[0].msg) { const newBody = JSON.stringify({ kind: body[0].kind, id: body[0].id, msg: body[0].msg.replace(stringToReplace, ''), }); return new HttpResponseError(`Http error response: (${error.status}) ${newBody}`, error.status, error.statusText, newBody, error.url); } else { return error; } } class RpcInjector { constructor(context) { this.context = context; } inject(signedOperationBytes) { return __awaiter(this, void 0, void 0, function* () { let hash; try { hash = yield this.context.rpc.injectOperation(signedOperationBytes); } catch (error) { const stringToStrip = '. You may want to use --replace to provide adequate fee and replace it'; if (error instanceof HttpResponseError && error.message.includes(stringToStrip)) { throw formatErrorMessage(error, stringToStrip); } else { throw error; } } return hash; }); } } /** * @category Error * @description Error that indicates the signer has been unconfigured in the TezosToolkit instance */ class UnconfiguredSignerError extends Error { constructor() { super('No signer has been configured. Please configure one by calling setProvider({signer}) on your TezosToolkit instance.'); this.name = 'UnconfiguredSignerError'; } } /** * @description Default signer implementation which does nothing and produce invalid signature */ class NoopSigner { publicKey() { return __awaiter(this, void 0, void 0, function* () { throw new UnconfiguredSignerError(); }); } publicKeyHash() { return __awaiter(this, void 0, void 0, function* () { throw new UnconfiguredSignerError(); }); } secretKey() { return __awaiter(this, void 0, void 0, function* () { throw new UnconfiguredSignerError(); }); } sign(_bytes, _watermark) { return __awaiter(this, void 0, void 0, function* () { throw new UnconfiguredSignerError(); }); } } function createObservableFromSubscription(sub) { return new Observable((subscriber) => { sub.on('data', (data) => { subscriber.next(data); }); sub.on('error', (error) => { subscriber.error(error); }); sub.on('close', () => { subscriber.complete(); }); return () => { sub.close(); }; }); } var DEFAULT_GAS_LIMIT; (function (DEFAULT_GAS_LIMIT) { DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["DELEGATION"] = 10600] = "DELEGATION"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["ORIGINATION"] = 10600] = "ORIGINATION"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["TRANSFER"] = 10600] = "TRANSFER"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["REVEAL"] = 1100] = "REVEAL"; })(DEFAULT_GAS_LIMIT || (DEFAULT_GAS_LIMIT = {})); var DEFAULT_FEE; (function (DEFAULT_FEE) { DEFAULT_FEE[DEFAULT_FEE["DELEGATION"] = 1257] = "DELEGATION"; DEFAULT_FEE[DEFAULT_FEE["ORIGINATION"] = 10000] = "ORIGINATION"; DEFAULT_FEE[DEFAULT_FEE["TRANSFER"] = 10000] = "TRANSFER"; DEFAULT_FEE[DEFAULT_FEE["REVEAL"] = 374] = "REVEAL"; })(DEFAULT_FEE || (DEFAULT_FEE = {})); var DEFAULT_STORAGE_LIMIT; (function (DEFAULT_STORAGE_LIMIT) { DEFAULT_STORAGE_LIMIT[DEFAULT_STORAGE_LIMIT["DELEGATION"] = 0] = "DELEGATION"; DEFAULT_STORAGE_LIMIT[DEFAULT_STORAGE_LIMIT["ORIGINATION"] = 257] = "ORIGINATION"; DEFAULT_STORAGE_LIMIT[DEFAULT_STORAGE_LIMIT["TRANSFER"] = 257] = "TRANSFER"; DEFAULT_STORAGE_LIMIT[DEFAULT_STORAGE_LIMIT["REVEAL"] = 0] = "REVEAL"; })(DEFAULT_STORAGE_LIMIT || (DEFAULT_STORAGE_LIMIT = {})); const COST_PER_BYTE = 250; var Protocols; (function (Protocols) { Protocols["Pt24m4xi"] = "Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd"; Protocols["PsBABY5H"] = "PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU"; Protocols["PsBabyM1"] = "PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS"; Protocols["PsCARTHA"] = "PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb"; Protocols["PsDELPH1"] = "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo"; Protocols["PtEdo2Zk"] = "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA"; Protocols["PsFLorena"] = "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i"; Protocols["PtGRANADs"] = "PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV"; Protocols["PtHangz2"] = "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx"; Protocols["PsiThaCa"] = "PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP"; Protocols["Psithaca2"] = "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A"; Protocols["PtJakart2"] = "PtJakart2xVj7pYXJBXrqHgd82rdkLey5ZeeGwDgPp9rhQUbSqY"; Protocols["PtKathman"] = "PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg"; Protocols["PtLimaPtL"] = "PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW"; Protocols["PtMumbaii"] = "PtMumbaiiFFEGbew1rRjzSPyzRbA51Tm3RVZL5suHPxSZYDhCEc"; Protocols["PtMumbai2"] = "PtMumbai2TmsJHNGRkD8v8YDbtao7BLUC3wjASn1inAKLFCjaH1"; Protocols["ProtoALpha"] = "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK"; })(Protocols || (Protocols = {})); const protocols = { '004': [Protocols.Pt24m4xi], '005': [Protocols.PsBABY5H, Protocols.PsBabyM1], '006': [Protocols.PsCARTHA], '007': [Protocols.PsDELPH1], '008': [Protocols.PtEdo2Zk], '009': [Protocols.PsFLorena], '010': [Protocols.PtGRANADs], '011': [Protocols.PtHangz2], '012': [Protocols.PsiThaCa, Protocols.Psithaca2], '013': [Protocols.PtJakart2], '014': [Protocols.PtKathman], '015': [Protocols.PtLimaPtL], '016': [Protocols.PtMumbai2], '017': [Protocols.ProtoALpha], }; var ChainIds; (function (ChainIds) { ChainIds["MAINNET"] = "NetXdQprcVkpaWU"; ChainIds["CARTHAGENET"] = "NetXjD3HPJJjmcd"; ChainIds["DELPHINET"] = "NetXm8tYqnMWky1"; ChainIds["EDONET"] = "NetXSgo1ZT2DRUG"; ChainIds["FLORENCENET"] = "NetXxkAx4woPLyu"; ChainIds["GRANADANET"] = "NetXz969SFaFn8k"; ChainIds["HANGZHOUNET"] = "NetXZSsxBpMQeAT"; ChainIds["ITHACANET"] = "NetXbhmtAbMukLc"; ChainIds["ITHACANET2"] = "NetXnHfVqm9iesp"; ChainIds["JAKARTANET2"] = "NetXLH1uAxK7CCh"; ChainIds["KATHMANDUNET"] = "NetXazhm4yetmff"; ChainIds["LIMANET"] = "NetXizpkH94bocH"; ChainIds["MUMBAINET"] = "NetXQw6nWSnrJ5t"; ChainIds["MUMBAINET2"] = "NetXgbcrNtXD2yA"; })(ChainIds || (ChainIds = {})); /** * @category Error * @description Error that indicates invalid smart contract parameters being passed or used */ class InvalidParameterError extends Error { constructor(smartContractMethodName, sigs, args) { super(`${smartContractMethodName} Received ${args.length} arguments while expecting one of the following signatures (${JSON.stringify(sigs)})`); this.smartContractMethodName = smartContractMethodName; this.sigs = sigs; this.args = args; this.name = 'Invalid parameters error'; } } /** * @category Error * @description Error that indicates an invalid delegation source contract address being passed or used */ class InvalidDelegationSource extends Error { constructor(source) { super(`Since Babylon delegation source can no longer be a contract address ${source}. Please use the smart contract abstraction to set your delegate.`); this.source = source; this.name = 'Invalid delegation source error'; } } /** * @category Error * @description Error that indicates an invalid smart contract code parameter being passed or used */ class InvalidCodeParameter extends Error { constructor(message, data) { super(message); this.message = message; this.data = data; this.name = 'InvalidCodeParameter'; } } /** * @category Error * @description Error that indicates invalid smart contract init parameter being passed or used */ class InvalidInitParameter extends Error { constructor(message, data) { super(message); this.message = message; this.data = data; this.name = 'InvalidInitParameter'; } } /** * @category Error * @description Error that indicates a failure when conducting a view simulation */ class ViewSimulationError extends Error { constructor(message, viewName, failWith, originalError) { super(message); this.message = message; this.viewName = viewName; this.failWith = failWith; this.originalError = originalError; this.name = 'ViewSimulationError'; } } const validateAndExtractFailwith = (error) => { if (isJsonString(error.body)) { const parsedError = JSON.parse(error.body); if (Array.isArray(parsedError) && 'with' in parsedError[parsedError.length - 1]) { return parsedError[parsedError.length - 1].with; } } }; const isJsonString = (str) => { try { JSON.parse(str); } catch (e) { return false; } return true; }; /** * @category Error * @description Error that indicates invalid or unconfigured context when executing a view */ class InvalidViewSimulationContext extends Error { constructor(info) { super(`${info} Please configure the context of the view execution in the executeView method.`); this.info = info; this.name = 'InvalidViewSimulationContext'; } } /** * @category Error * @description Error that indicates a mistake happening during the reveal operation */ class RevealOperationError extends Error { constructor(message) { super(message); this.message = message; this.name = 'RevealOperationError'; } } /** * @category Error * @description Error that indicates a mistake in the parameters in the preparation of an Origination operation */ class OriginationParameterError extends Error { constructor(message) { super(message); this.message = message; this.name = 'OriginationParameterError'; } } class IntegerError extends Error { constructor(message) { super(message); this.message = message; this.name = 'IntegerError'; } } const createActivationOperation = ({ pkh, secret }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.ACTIVATION, pkh, secret, }; }); const createOriginationOperation = ({ code, init, balance = '0', delegate, storage, fee = DEFAULT_FEE.ORIGINATION, gasLimit = DEFAULT_GAS_LIMIT.ORIGINATION, storageLimit = DEFAULT_STORAGE_LIMIT.ORIGINATION, mutez = false, }) => __awaiter(void 0, void 0, void 0, function* () { if (storage !== undefined && init !== undefined) { throw new OriginationParameterError('Storage and Init cannot be set a the same time. Please either use storage or init but not both.'); } if (!Array.isArray(code)) { throw new InvalidCodeParameter('Wrong code parameter type, expected an array', code); } let contractStorage; if (storage !== undefined) { const storageType = code.find((p) => 'prim' in p && p.prim === 'storage'); if ((storageType === null || storageType === void 0 ? void 0 : storageType.args) === undefined) { throw new InvalidCodeParameter('The storage section is missing from the script', code); } const schema = new Schema(storageType.args[0]); // TODO contractStorage = schema.Encode(storage); } else if (init !== undefined && typeof init === 'object') { contractStorage = init; } else { throw new InvalidInitParameter('Wrong init parameter type, expected JSON Michelson', init); } const script = { code, storage: contractStorage, }; if (isNaN(Number(balance))) { throw new IntegerError(`Unexpected Invalid Integer ${balance}`); } const operation = { kind: OpKind.ORIGINATION, fee, gas_limit: gasLimit, storage_limit: storageLimit, balance: mutez ? balance.toString() : format('tz', 'mutez', balance).toString(), script, }; if (delegate) { operation.delegate = delegate; } return operation; }); const createTransferOperation = ({ to, amount, parameter, fee = DEFAULT_FEE.TRANSFER, gasLimit = DEFAULT_GAS_LIMIT.TRANSFER, storageLimit = DEFAULT_STORAGE_LIMIT.TRANSFER, mutez = false, }) => __awaiter(void 0, void 0, void 0, function* () { const operation = { kind: OpKind.TRANSACTION, fee, gas_limit: gasLimit, storage_limit: storageLimit, amount: mutez ? amount.toString() : format('tz', 'mutez', amount).toString(), destination: to, parameters: parameter, }; return operation; }); const createSetDelegateOperation = ({ delegate, source, fee = DEFAULT_FEE.DELEGATION, gasLimit = DEFAULT_GAS_LIMIT.DELEGATION, storageLimit = DEFAULT_STORAGE_LIMIT.DELEGATION, }) => __awaiter(void 0, void 0, void 0, function* () { const operation = { kind: OpKind.DELEGATION, source, fee, gas_limit: gasLimit, storage_limit: storageLimit, delegate, }; return operation; }); const createRegisterDelegateOperation = ({ fee = DEFAULT_FEE.DELEGATION, gasLimit = DEFAULT_GAS_LIMIT.DELEGATION, storageLimit = DEFAULT_STORAGE_LIMIT.DELEGATION, }, source) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.DELEGATION, fee, gas_limit: gasLimit, storage_limit: storageLimit, delegate: source, }; }); const createRevealOperation = ({ fee = DEFAULT_FEE.REVEAL, gasLimit = DEFAULT_GAS_LIMIT.REVEAL, storageLimit = DEFAULT_STORAGE_LIMIT.REVEAL, }, source, publicKey) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.REVEAL, fee, public_key: publicKey, source, gas_limit: gasLimit, storage_limit: storageLimit, }; }); const createRegisterGlobalConstantOperation = ({ value, source, fee, gasLimit, storageLimit, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.REGISTER_GLOBAL_CONSTANT, value, fee, gas_limit: gasLimit, storage_limit: storageLimit, source, }; }); const createTransferTicketOperation = ({ ticketContents, ticketTy, ticketTicketer, ticketAmount, destination, entrypoint, source, fee, gasLimit, storageLimit, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.TRANSFER_TICKET, fee, gas_limit: gasLimit, storage_limit: storageLimit, source, ticket_contents: ticketContents, ticket_ty: ticketTy, ticket_ticketer: ticketTicketer, ticket_amount: ticketAmount, destination, entrypoint, }; }); const createIncreasePaidStorageOperation = ({ source, fee, gasLimit, storageLimit, amount, destination, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.INCREASE_PAID_STORAGE, source, fee, gas_limit: gasLimit, storage_limit: storageLimit, amount, destination, }; }); const createDrainDelegateOperation = ({ consensus_key, delegate, destination, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.DRAIN_DELEGATE, consensus_key, delegate, destination, }; }); const createBallotOperation = ({ source, proposal, ballot }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.BALLOT, source, proposal, ballot, }; }); const createProposalsOperation = ({ source, proposals }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.PROPOSALS, source, proposals, }; }); const createUpdateConsensusKeyOperation = ({ source, fee, gasLimit, storageLimit, pk, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.UPDATE_CONSENSUS_KEY, source, fee, gas_limit: gasLimit, storage_limit: storageLimit, pk, }; }); const createSmartRollupAddMessagesOperation = ({ source, fee, gasLimit, storageLimit, message, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.SMART_ROLLUP_ADD_MESSAGES, source, fee, gas_limit: gasLimit, storage_limit: storageLimit, message, }; }); const createSmartRollupOriginateOperation = ({ source, fee, gasLimit, storageLimit, pvmKind, kernel, originationProof, parametersType, }) => __awaiter(void 0, void 0, void 0, function* () { return { kind: OpKind.SMART_ROLLUP_ORIGINATE, source, fee, gas_limit: gasLimit, storage_limit: storageLimit, pvm_kind: pvmKind, kernel, origination_proof: originationProof, parameters_ty: parametersType, }; }); const attachKind = (op, kind) => { return Object.assign(Object.assign({}, op), { kind }); }; const findWithKind = (arr, kind) => { if (Array.isArray(arr)) { const found = arr.find((op) => op.kind === kind); if (found && isKind(found, kind)) { return found; } } }; const isKind = (op, kind) => { return op.kind === kind; }; const isOpWithFee = (op) => { return ([ 'transaction', 'delegation', 'origination', 'reveal', 'register_global_constant', 'increase_paid_storage', 'tx_rollup_origination', 'tx_rollup_submit_batch', 'transfer_ticket', 'update_consensus_key', 'smart_rollup_add_messages', 'smart_rollup_originate', ].indexOf(op.kind) !== -1); }; const isOpRequireReveal = (op) => { return ([ 'transaction', 'delegation', 'origination', 'register_global_constant', 'increase_paid_storage', 'tx_rollup_origination', 'tx_rollup_submit_batch', 'transfer_ticket', 'update_consensus_key', 'smart_rollup_add_messages', 'smart_rollup_originate', ].indexOf(op.kind) !== -1); }; const hasMetadata = (op) => { return 'metadata' in op; }; const hasMetadataWithResult = (op) => { return hasMetadata(op) && 'operation_result' in op.metadata; }; const hasMetadataWithInternalOperationResult = (op) => { return hasMetadata(op) && 'internal_operation_results' in op.metadata; }; const isErrorWithMessage = (error) => { return 'with' in error; }; /** * @category Error * @description Generic tezos error that will be thrown when a mistake occurs when doing an operation; more details here https://tezos.gitlab.io/api/errors.html */ class TezosOperationError extends Error { constructor(errors, errorDetails) { super(); this.errors = errors; this.errorDetails = errorDetails; this.name = 'TezosOperationError'; // Last error is 'often' the one with more detail const lastError = errors[errors.length - 1]; this.id = lastError.id; this.kind = lastError.kind; this.message = `(${this.kind}) ${this.id}`; if (isErrorWithMessage(lastError)) { if (lastError.with.string) { this.message = lastError.with.string; } else if (lastError.with.int) { this.message = lastError.with.int; } else { this.message = JSON.stringify(lastError.with); } } } } /** * @category Error * @description Tezos error that will be thrown when a mistake happens during the preapply stage */ class TezosPreapplyFailureError extends Error { constructor(result) { super('Preapply returned an unexpected result'); this.result = result; this.name = 'TezosPreapplyFailureError'; } } // Flatten all operation content results and internal operation results into a single array // Some cases where we can have multiple operation results or internal operation results are: // - When an operation includes a reveal operation // - When an operation is made using the batch API // - Smart contract call can contains internal operation results when they call other smart contract internally or originate contracts const flattenOperationResult = (response) => { const results = Array.isArray(response) ? response : [response]; const returnedResults = []; for (let i = 0; i < results.length; i++) { for (let j = 0; j < results[i].contents.length; j++) { const content = results[i].contents[j]; if (hasMetadataWithResult(content)) { returnedResults.push(Object.assign({ fee: content.fee }, content.metadata.operation_result)); if (Array.isArray(content.metadata.internal_operation_results)) { content.metadata.internal_operation_results.forEach((x) => returnedResults.push(x.result)); } } } } return returnedResults; }; /*** * @description Flatten all error from preapply response (including internal error) */ const flattenErrors = (response, status = 'failed') => { const results = Array.isArray(response) ? response : [response]; let errors = []; // Transaction that do not fail will be backtracked in case one failure occur for (let i = 0; i < results.length; i++) { for (let j = 0; j < results[i].contents.length; j++) { const content = results[i].contents[j]; if (hasMetadata(content)) { if (hasMetadataWithResult(content) && content.metadata.operation_result.status === status) { errors = errors.concat(content.metadata.operation_result.errors || []); } if (hasMetadataWithInternalOperationResult(content) && Array.isArray(content.metadata.internal_operation_results)) { for (const internalResult of content.metadata.internal_operation_results) { if ('result' in internalResult && internalResult.result.status === status) { errors = errors.concat(internalResult.result.errors || []); } } } } } } return errors; }; /** * @category Error * @description Error that indicates a general failure happening during an origination operation */ class OriginationOperationError extends Error { constructor(message) { super(message); this.message = message; this.name = 'OriginationOperationError'; } } /** * @category Error * @description Error that indicates an invalid estimate value being passed */ class InvalidEstimateValueError extends Error { constructor(message) { super(message); this.message = message; this.name = 'InvalidEstimateValueError'; } } /** * @category Error * @description Error that indicates invalid confirmation count has been passed or configured */ class InvalidConfirmationCountError extends Error { constructor(message) { super(message); this.message = message; this.name = 'InvalidConfirmationCountError'; } } /** * @category Error * @description Error that indicates undefined confirmation has not been specified or configured */ class ConfirmationUndefinedError extends Error { constructor(message) { super(message); this.message = message; this.name = 'ConfirmationUndefinedError'; } } /** * @category Error * @description Error that indicates an invalid filter expression being passed or used */ class InvalidFilterExpressionError extends Error { constructor(message) { super(message); this.message = message; this.name = 'InvalidFilterExpressionError'; } } /** * @category Error * @description Error that indicates an error being returned from the RPC response */ class RPCResponseError extends Error { constructor(message) { super(message); this.message = message; this.name = 'RPCResponseError'; } } /** * @category Error * @description Error that indicates invalid Preparation parameters being passed */ class PublicKeyNotFoundError extends Error { constructor() { super(`Unable to retrieve public key from signer. If you are using a wallet, make sure your account is revealed`); this.name = 'PublicKeyNotFoundError'; } } /** * @description Utility class to interact with Tezos operations */ class Operation { /** * * @param hash Operation hash * @param raw Raw operation that was injected * @param context Taquito context allowing access to rpc and signer * @throws {@link InvalidOperationHashError} */ constructor(hash, raw, results, context) { this.hash = hash; this.raw = raw; this.results = results; this.context = context; this._pollingConfig$ = new ReplaySubject(1); this.currentHead$ = this._pollingConfig$.pipe(switchMap((config) => { return new BehaviorSubject(config).pipe(timeoutWith(config.timeout * 1000, throwError(new Error('Confirmation polling timed out')))); }), switchMap(() => { return defer(() => createObservableFromSubscription(this.context.stream.subscribeBlock('head'))).pipe(switchMap((newHead) => { var _a, _b; const prevHead = (_b = (_a = this.lastHead) === null || _a === void 0 ? void 0 : _a.header.level) !== null && _b !== void 0 ? _b : newHead.header.level - 1; return range(prevHead + 1, newHead.header.level - prevHead - 1).pipe(concatMap((level) => this.context.readProvider.getBlock(level)), endWith(newHead)); }), tap((newHead) => (this.lastHead = newHead))); }), shareReplay({ refCount: true })); // Observable that emit once operation is seen in a block this.confirmed$ = this.currentHead$.pipe(map((head) => { for (let i = 3; i >= 0; i--) { head.operations[i].forEach((op) => { if (op.hash === this.hash) { this._foundAt = head.header.level; } }); } if (head.header.level - this._foundAt >= 0) { return this._foundAt; } }), filter((x) => x !== undefined), first(), shareReplay()); this._foundAt = Number.POSITIVE_INFINITY; if (validateOperation(this.hash) !== ValidationResult.VALID) { throw new InvalidOperationHashError(this.hash); } this.confirmed$ .pipe(first(), catchError(() => { return of(EMPTY); })) .subscribe(); } get includedInBlock() { return this._foundAt; } get revealOperation() { return (Array.isArray(this.results) && this.results.find((op) => op.kind === 'reveal')); } get revealStatus() { if (this.revealOperation) { return this.revealOperation.metadata.operation_result.status; } else { return 'unknown'; } } get status() { return (this.results.map((result) => { if (hasMetadataWithResult(result)) { return result.metadata.operation_result.status; } else { return 'unknown'; } })[0] || 'unknown'); } /** * * @param confirmations [0] Number of confirmation to wait for * @param timeout [180] Timeout */ confirmation(confirmations, timeout) { return __awaiter(this, void 0, void 0, function* () { if (typeof confirmations !== 'undefined' && confirmations < 1) { throw new InvalidConfirmationCountError('Confirmation count must be at least 1'); } const { defaultConfirmationCount, confirmationPollingTimeoutSecond } = this.context.config; this._pollingConfig$.next({ timeout: timeout || confirmationPollingTimeoutSecond, }); const conf = confirmations !== undefined ? confirmations : defaultConfirmationCount; return new Promise((resolve, reject) => { this.confirmed$ .pipe(switchMap(() => this.currentHead$), filter((head) => head.header.level - this._foundAt >= conf - 1), first()) .subscribe((_) => { resolve(this._foundAt + (conf - 1)); }, reject); }); }); } } class BatchOperation extends Operation { constructor(hash, params, source, raw, results, context) { super(hash, raw, results, context); this.params = params; this.source = source; } sumProp(arr, prop) { return arr.reduce((prev, current) => { return prop in current ? Number(current[prop]) + prev : prev; }, 0); } getOriginatedContractAddresses() { const originationOpResults = this.results.filter((x) => x.kind === 'origination'); let addresses = []; for (const res of originationOpResults) { if (res.metadata.operation_result.originated_contracts) { addresses = [...addresses, ...res.metadata.operation_result.originated_contracts]; } } return addresses; } get status() { return (this.results .filter((result) => BATCH_KINDS.indexOf(result.kind) !== -1) .map((result) => { if (hasMetadataWithResult(result)) { return result.metadata.operation_result.status; } else { return 'unknown'; } })[0] || 'unknown'); } get fee() { return this.sumProp(this.params, 'fee'); } get gasLimit() { return this.sumProp(this.params, 'gas_limit'); } get storageLimit() { return this.sumProp(this.params, 'storage_limit'); } get consumedGas() { BigNumber.config({ DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_UP }); return new BigNumber(this.consumedMilliGas).dividedBy(1000).toString(); } get consumedMilliGas() { return String(this.sumProp(flattenOperationResult({ contents: this.results }), 'consumed_milligas')); } get storageDiff() { return String(this.sumProp(flattenOperationResult({ contents: this.results }), 'paid_storage_size_diff')); } get errors() { return flattenErrors({ contents: this.results }); } } class Provider { constructor(context) { this.context = context; } get rpc() { return this.context.rpc; } get signer() { return this.context.signer; } forge({ opOb: { branch, contents, protocol }, counter }) { return __awaiter(this, void 0, void 0, function* () { const forgedBytes = yield this.context.forger.forge({ branch, contents }); return { opbytes: forgedBytes, opOb: { branch, contents, protocol, }, counter, }; }); } estimate(_a, estimator) { var { fee, gasLimit, storageLimit } = _a, rest = __rest(_a, ["fee", "gasLimit", "storageLimit"]); return __awaiter(this, void 0, void 0, function* () { let calculatedFee = fee; let calculatedGas = gasLimit; let calculatedStorage = storageLimit; if (calculatedFee && calculatedFee % 1 !== 0) { throw new InvalidEstimateValueError(`Fee value must not be a decimal: ${calculatedFee}`); } if (calculatedGas && calculatedGas % 1 !== 0) { throw new InvalidEstimateValueError(`Gas Limit value must not be a decimal: ${calculatedGas}`); } if (calculatedStorage && calculatedStorage % 1 !== 0) { throw new InvalidEstimateValueError(`Storage Limit value must not be a decimal: ${calculatedStorage}`); } if (fee === undefined || gasLimit === undefined || storageLimit === undefined) { const estimation = yield estimator(Object.assign({ fee, gasLimit, storageLimit }, rest)); calculatedFee !== null && calculatedFee !== void 0 ? calculatedFee : (calculatedFee = estimation.suggestedFeeMutez); calculatedGas !== null && calculatedGas !== void 0 ? calculatedGas : (calculatedGas = estimation.gasLimit); calculatedStorage !== null && calculatedStorage !== void 0 ? calculatedStorage : (calculatedStorage = estimation.storageLimit); } return { fee: calculatedFee, gasLimit: calculatedGas, storageLimit: calculatedStorage, }; }); } getRPCOp(param) { return __awaiter(this, void 0, void 0, function* () { switch (param.kind) { case OpKind.TRANSACTION: return createTransferOperation(Object.assign({}, param)); case OpKind.ORIGINATION: return createOriginationOperation(yield this.context.parser.prepareCodeOrigination(Object.assign({}, param))); case OpKind.DELEGATION: return createSetDelegateOperation(Object.assign({}, param)); case OpKind.REGISTER_GLOBAL_CONSTANT: return createRegisterGlobalConstantOperation(Object.assign({}, param)); case OpKind.INCREASE_PAID_STORAGE: return createIncreasePaidStorageOperation(Object.assign({}, param)); case OpKind.TRANSFER_TICKET: return createTransferTicketOperation(Object.assign({}, param)); case OpKind.SMART_ROLLUP_ADD_MESSAGES: return createSmartRollupAddMessagesOperation(Object.assign({}, param)); case OpKind.SMART_ROLLUP_ORIGINATE: return createSmartRollupOriginateOperation(Object.assign({}, param)); default: throw new InvalidOperationKindError(param.kind); } }); } simulate(op) { return __awaiter(this, void 0, void 0, function* () { return { opResponse: yield this.rpc.runOperation(op), op, context: this.context.clone(), }; }); } isRevealOpNeeded(op, pkh) { return __awaiter(this, void 0, void 0, function* () { return !(yield this.isAccountRevealRequired(pkh)) || !this.isRevealRequiredForOpType(op) ? false : true; }); } isAccountRevealRequired(publicKeyHash) { return __awaiter(this, void 0, void 0, function* () { return !(yield this.context.readProvider.isAccountRevealed(publicKeyHash, 'head')); }); } isRevealRequiredForOpType(op) { let opRequireReveal = false; for (const operation of op) { if (isOpRequireReveal(operation)) { opRequireReveal = true; } } return opRequireReveal; } signAndInject(forgedBytes) { return __awaiter(this, void 0, void 0, function* () { const signed = yield this.signer.sign(forgedBytes.opbytes, new Uint8Array([3])); forgedBytes.opbytes = signed.sbytes; forgedBytes.opOb.signature = signed.prefixSig; const opResponse = []; const results = yield this.rpc.preapplyOperations([forgedBytes.opOb]); if (!Array.isArray(results)) { throw new TezosPreapplyFailureError(results); } for (let i = 0; i < results.length; i++) { for (let j = 0; j < results[i].contents.length; j++) { opResponse.push(results[i].contents[j]); } } const errors = flattenErrors(results); if (errors.length) { throw new TezosOperationError(errors, 'Error occurred during validation simulation of operation'); } return { hash: yield this.context.injector.inject(forgedBytes.opbytes), forgedBytes, opResponse, context: this.context.clone(), }; }); } } class WalletOperationBatch { constructor(walletProvider, context) { this.walletProvider = walletProvider; this.context = context; this.operations = []; } /** * * @description Add a transaction operation to the batch * * @param params Transfer operation parameter */ withTransfer(params) { const toValidation = validateAddress(params.to); if (toValidation !== ValidationResult.VALID) { throw new InvalidAddressError(params.to, invalidErrorDetail(toValidation)); } this.operations.push(Object.assign({ kind: OpKind.TRANSACTION }, params)); return this; } /** * * @description Add a contract call to the batch * * @param params Call a contract method * @param options Generic operation parameters */ withContractCall(params, options = {}) { return this.withTransfer(params.toTransferParams(options)); } /** * * @description Add a delegation operation to the batch * * @param params Delegation operation parameter */ withDelegation(params) { var _a; const delegateValidation = validateAddress((_a = params.delegate) !== null && _a !== void 0 ? _a : ''); if (params.delegate && delegateValidation !== ValidationResult.VALID) { throw new InvalidAddressError(params.delegate, invalidErrorDetail(delegateValidation)); } this.operations.push(Object.assign({ kind: OpKind.DELEGATION }, params)); return this; } /** * * @description Add an origination operation to the batch * * @param params Origination operation parameter */ withOrigination(params) { this.operations.push(Object.assign({ kind: OpKind.ORIGINATION }, params)); return this; } /** * * @description Add an IncreasePaidStorage operation to the batch * * @param param IncreasePaidStorage operation parameter */ withIncreasePaidStorage(params) { const destinationValidation = validateAddress(params.destination); if (destinationValidation !== ValidationResult.VALID) { throw new InvalidAddressError(params.destination, invalidErrorDetail(destinationValidation)); } this.operations.push(Object.assign({ kind: OpKind.INCREASE_PAID_STORAGE }, params)); return this; } mapOperation(param) { return __awaiter(this, void 0, void 0, function* () { switch (param.kind) { case OpKind.TRANSACTION: return this.walletProvider.mapTransferParamsToWalletParams(() => __awaiter(this, void 0, void 0, function* () { return param; })); case OpKind.ORIGINATION: return this.walletProvider.mapOriginateParamsToWalletParams(() => __awaiter(this, void 0, void 0, function* () { return this.context.parser.prepareCodeOrigination(Object.assign({}, param)); })); case OpKind.DELEGATION: return this.walletProvider.mapDelegateParamsToWalletParams(() => __awaiter(this, void 0, void 0, function* () { return param; })); case OpKind.INCREASE_PAID_STORAGE: return this.walletProvider.mapIncreasePaidStorageWalletParams(() => __awaiter(this, void 0, void 0, function* () { return param; })); default: throw new InvalidOperationKindError$1(JSON.stringify(param.kind)); } }); } /** * * @description Add a group operation to the batch. Operation will be applied in the order they are in the params array * * @param params Operations parameter * @throws {@link InvalidOperationKindError} */ with(params) { for (const param of params) { switch (param.kind) { case OpKind.TRANSACTION: this.withTransfer(param); break; case OpKind.ORIGINATION: this.withOrigination(param); break; case OpKind.DELEGATION: this.withDelegation(param); break; case OpKind.INCREASE_PAID_STORAGE: this.withIncreasePaidStorage(param); break; default: throw new InvalidOperationKindError$1(JSON.stringify(param.kind)); } } return this; } /** * * @description Submit batch operation to wallet * */ send() { return __awaiter(this, void 0, void 0, function* () { const ops = []; for (const op of this.operations) { ops.push(yield this.mapOperation(op)); } const opHash = yield this.walletProvider.sendOperations(ops); return this.context.operationFactory.createBatchOperation(opHash); }); } } class Wallet { constructor(context) { this.context = context; this.walletCommand = (send) => { return { send, }; }; } get walletProvider() { return this.context.walletProvider; } /** * @description Retrieve the PKH of the account that is currently in use by the wallet * * @param option Option to use while fetching the PKH. * If forceRefetch is specified the wallet provider implementation will refetch the PKH from the wallet */ pkh({ forceRefetch } = {}) { return __awaiter(this, void 0, void 0, function* () { if (!this._pkh || forceRefetch) { this._pkh = yield this.walletProvider.getPKH(); } return this._pkh; }); } /** * * @description Originate a new contract according to the script in parameters. * * @returns An operation handle with the result from the rpc node * * @param originateParams Originate operation parameter */ originate(params) { return this.walletCommand(() => __awaiter(this, void 0, void 0, function* () { const mappedParams = yield this.walletProvider.mapOriginateParamsToWalletParams(() => this.context.parser.prepareCodeOrigination(Object.assign({}, params))); const opHash = yield this.walletProvider.sendOperations([mappedParams]); return this.context.operationFactory.createOriginationOperation(opHash); })); } /** * * @description Set the delegate for a contract. * * @returns An operation handle with the result from the rpc node * * @param delegateParams operation parameter */ setDelegate(params) { var _a; const delegateValidation = validateAddress((_a = params.delegate) !== null && _a !== void 0 ? _a : ''); if (params.delegate && delegateValidation !== ValidationResult.VALID) { throw new InvalidAddressError(params.delegate, invalidErrorDetail(delegateValidation)); } return this.walletCommand(() => __awaiter(this, void 0, void 0, function* () { const mappedParams = yield this.walletProvider.mapDelegateParamsToWalletParams(() => __awaiter(this, void 0, void 0, function* () { return params;