UNPKG

@taquito/taquito

Version:

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

1,234 lines (1,211 loc) 280 kB
import { OpKind, RpcClient } from '@taquito/rpc'; export { OpKind } from '@taquito/rpc'; import { HttpResponseError, STATUS_CODE } from '@taquito/http-utils'; import { TezosToolkitConfigError, ParameterValidationError, RpcError, TaquitoError, NetworkError, InvalidOperationHashError, InvalidAddressError, InvalidOperationKindError as InvalidOperationKindError$1, InvalidContractAddressError, InvalidViewParameterError, DeprecationError, InvalidChainIdError, PublicKeyNotFoundError, InvalidAmountError, InvalidKeyHashError } from '@taquito/core'; import { Observable, ReplaySubject, BehaviorSubject, throwError, defer, range, of, EMPTY, combineLatest, from, concat, Subject, NEVER, timer } from 'rxjs'; import { switchMap, timeout, concatMap, endWith, tap, shareReplay, map, filter, first, catchError, share, distinctUntilChanged, takeWhile, startWith, mergeMap, takeUntil, retry, pluck, distinctUntilKeyChanged, publish, refCount } from 'rxjs/operators'; import { Schema, ParameterSchema, ViewSchema, EventSchema, MichelsonMap } from '@taquito/michelson-encoder'; export { MichelsonMap, UnitValue } from '@taquito/michelson-encoder'; import { format, validateOperation, ValidationResult, InvalidOperationKindError, validateAddress, invalidDetail, validateContractAddress, validateChain, validateKeyHash, InvalidKeyHashError as InvalidKeyHashError$1, encodeExpr } from '@taquito/utils'; import BigNumber, { BigNumber as BigNumber$1 } from 'bignumber.js'; 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; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; 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 no signer has been configured in the TezosToolkit instance */ class UnconfiguredSignerError extends TezosToolkitConfigError { constructor() { super(); this.name = 'UnconfiguredSignerError'; this.message = 'No signer has been configured. Please configure one by calling setProvider({signer}) on your TezosToolkit instance.'; } } /** * @description Default signer implementation which does nothing and produce invalid signature * @throw {@link UnconfiguredSignerError} */ 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"; /* This is used for gas_limit. There is no harm in setting a higher limit. Only if an account has a balance that is very close to the total gas consumption, then this margin can fail the operation. Another benefit of this higher value is that then Dapps build with Taquito 17 can still work with Mumbainet, as this value is higher than the reveal cost in Mumbai. */ DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["REVEAL_TZ1"] = 1000] = "REVEAL_TZ1"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["REVEAL_TZ2"] = 1000] = "REVEAL_TZ2"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["REVEAL_TZ3"] = 2000] = "REVEAL_TZ3"; DEFAULT_GAS_LIMIT[DEFAULT_GAS_LIMIT["REVEAL_TZ4"] = 2000] = "REVEAL_TZ4"; })(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["PtNairobi"] = "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf"; 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.PtNairobi], '018': [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["NAIROBINET"] = "NetXyuzvDo2Ugzb"; })(ChainIds || (ChainIds = {})); const getRevealGasLimit = (address) => Math.round((getRevealGasLimitInternal(address) * 11) / 10); const getRevealGasLimitInternal = (address) => { switch (address.substring(0, 3)) { case 'tz1': return DEFAULT_GAS_LIMIT.REVEAL_TZ1; case 'tz2': return DEFAULT_GAS_LIMIT.REVEAL_TZ2; case 'tz3': return DEFAULT_GAS_LIMIT.REVEAL_TZ3; case 'tz4': return DEFAULT_GAS_LIMIT.REVEAL_TZ4; default: throw new Error(`Cannot estimate reveal gas limit for ${address}`); } }; /** * @category Error * @description Error that indicates invalid smart contract parameters being passed or used */ class InvalidParameterError extends ParameterValidationError { constructor(smartContractMethodName, sigs, invalidParams) { super(); this.smartContractMethodName = smartContractMethodName; this.sigs = sigs; this.invalidParams = invalidParams; this.name = 'InvalidParameterError'; this.message = `${smartContractMethodName} Received ${invalidParams.length} arguments while expecting one of the following signatures (${JSON.stringify(sigs)})`; } } /** * @category Error * @description Error that indicates an invalid delegation source contract address being passed or used */ class InvalidDelegationSource extends ParameterValidationError { constructor(source) { super(); this.source = source; this.name = `InvalidDelegationSource`; this.message = `Since Babylon delegation source can no longer be a contract address ${source}. Please use the smart contract abstraction to set your delegate.`; } } /** * @category Error * @description Error that indicates an invalid smart contract code parameter being passed or used */ class InvalidCodeParameter extends ParameterValidationError { constructor(message, data) { super(); 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 ParameterValidationError { constructor(message, data) { super(); 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 RpcError { constructor(message, viewName, failWith, cause) { super(); this.message = message; this.viewName = viewName; this.failWith = failWith; this.cause = cause; 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 ParameterValidationError { constructor(info) { super(); this.info = info; this.name = 'InvalidViewSimulationContext'; this.message = `${info} Please configure the context of the view execution in the executeView method.`; } } /** * @category Error * @description Error that indicates a mistake happening during the reveal operation */ class RevealOperationError extends RpcError { constructor(message) { super(); 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 ParameterValidationError { constructor(message) { super(); this.message = message; this.name; } } /** * @category Error * @description Error that indicates an invalid balance being passed or used */ class InvalidBalanceError extends ParameterValidationError { constructor(message) { super(); this.message = message; this.name = 'InvalidBalanceError'; } } 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 InvalidBalanceError(`Invalid Balance "${balance}", cannot be converted to a number`); } 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 = undefined, 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 !== null && gasLimit !== void 0 ? gasLimit : getRevealGasLimit(source), 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 RpcError { 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(); this.result = result; this.name = 'TezosPreapplyFailureError'; this.message = 'Preapply returned an unexpected result'; } } // 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) && 'fee' in 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 TaquitoError { constructor(message) { super(); this.message = message; this.name = 'OriginationOperationError'; } } /** * @category Error * @description Error that indicates an invalid estimate value being passed */ class InvalidEstimateValueError extends ParameterValidationError { constructor(message) { super(); this.message = message; this.name = 'InvalidEstimateValueError'; } } /** * @category Error * @description Error that indicates invalid confirmation count has been passed or configured */ class InvalidConfirmationCountError extends ParameterValidationError { constructor(invalidConfirmations) { super(); this.invalidConfirmations = invalidConfirmations; this.name = 'InvalidConfirmationCountError'; this.message = `Invalid confirmation count ${invalidConfirmations} expecting at least 1`; } } /** * @category Error * @description Error that indicates that confirmation polling timed out */ class ConfirmationTimeoutError extends NetworkError { constructor(message) { super(); this.message = message; this.name = 'ConfirmationTimeoutError'; } } /** * @category Error * @description Error that indicates an error being returned from the RPC response */ class RPCResponseError extends RpcError { constructor(message, cause) { super(); this.message = message; this.cause = cause; this.name = 'RPCResponseError'; } } /** * @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(timeout({ each: config.timeout * 1000, with: () => throwError(() => new ConfirmationTimeoutError(`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(confirmations); } 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)) { const opResult = result.metadata.operation_result; return opResult.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); } }); } runOperation(op) { return __awaiter(this, void 0, void 0, function* () { return { opResponse: yield this.rpc.runOperation(op), op, context: this.context.clone(), }; }); } simulate(op) { return __awaiter(this, void 0, void 0, function* () { return { opResponse: yield this.rpc.simulateOperation(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, invalidDetail(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, invalidDetail(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, invalidDetail(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; } /** * @d