UNPKG

@mavrykdynamics/taquito

Version:

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

158 lines (157 loc) 7.82 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WalletOperation = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const receipt_1 = require("./receipt"); const taquito_utils_1 = require("@mavrykdynamics/taquito-utils"); const errors_1 = require("../errors"); const errors_2 = require("./errors"); const taquito_core_1 = require("@mavrykdynamics/taquito-core"); const MAX_BRANCH_ANCESTORS = 60; /** * @description WalletOperation allows to monitor operation inclusion on chains and surface information related to the operation */ class WalletOperation { operationResults() { return __awaiter(this, void 0, void 0, function* () { return this._operationResult.pipe((0, operators_1.first)()).toPromise(); }); } /** * @description Receipt expose the total amount of mavryk token burn and spent on fees * The promise returned by receipt will resolve only once the transaction is included */ receipt() { return __awaiter(this, void 0, void 0, function* () { const results = yield this.operationResults(); if (!results) { throw new errors_2.ObservableError('Unable to get operation results'); } return (0, receipt_1.receiptFromOperation)(results); }); } /** * * @param opHash Operation hash * @param raw Raw operation that was injected * @param context Taquito context allowing access to rpc and signer * @throws {InvalidOperationHashError} */ constructor(opHash, context, _newHead$) { this.opHash = opHash; this.context = context; this._newHead$ = _newHead$; this._operationResult = new rxjs_1.ReplaySubject(1); this._includedInBlock = new rxjs_1.ReplaySubject(1); this._included = false; this.newHead$ = this._newHead$.pipe((0, operators_1.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 (0, rxjs_1.range)(prevHead + 1, newHead.header.level - prevHead - 1).pipe((0, operators_1.concatMap)((level) => this.context.readProvider.getBlock(level)), (0, operators_1.endWith)(newHead)); }), (0, operators_1.tap)((newHead) => (this.lastHead = newHead)), (0, operators_1.share)({ connector: () => new rxjs_1.ReplaySubject(1), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false, })); // Observable that emit once operation is seen in a block this.confirmed$ = this.newHead$.pipe((0, operators_1.map)((head) => { for (const opGroup of head.operations) { for (const op of opGroup) { if (op.hash === this.opHash) { this._included = true; this._includedInBlock.next(head); this._operationResult.next(op.contents); // Return the block where the operation was found return head; } } } }), (0, operators_1.filter)((x) => { return typeof x !== 'undefined'; }), (0, operators_1.first)(), (0, operators_1.share)({ connector: () => new rxjs_1.ReplaySubject(1), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false, })); if ((0, taquito_utils_1.validateOperation)(this.opHash) !== taquito_utils_1.ValidationResult.VALID) { throw new taquito_core_1.InvalidOperationHashError(this.opHash); } this.confirmed$ .pipe((0, operators_1.first)(), (0, operators_1.catchError)(() => (0, rxjs_1.of)(undefined))) .subscribe(); } getCurrentConfirmation() { return __awaiter(this, void 0, void 0, function* () { if (!this._included) { return 0; } return (0, rxjs_1.combineLatest)([this._includedInBlock, (0, rxjs_1.from)(this.context.readProvider.getBlock('head'))]) .pipe((0, operators_1.map)(([foundAtBlock, head]) => { return head.header.level - foundAtBlock.header.level + 1; }), (0, operators_1.first)()) .toPromise(); }); } isInCurrentBranch(tipBlockIdentifier = 'head') { return __awaiter(this, void 0, void 0, function* () { // By default it is assumed that the operation is in the current branch if (!this._included) { return true; } const tipBlockHeaderLevel = yield this.context.readProvider.getBlockLevel(tipBlockIdentifier); const inclusionBlock = yield this._includedInBlock.pipe((0, operators_1.first)()).toPromise(); if (!inclusionBlock) { throw new errors_2.ObservableError('Inclusion block is undefined'); } const levelDiff = (tipBlockHeaderLevel - inclusionBlock.header.level); // Block produced before the operation is included are assumed to be part of the current branch if (levelDiff <= 0) { return true; } const tipBlockLevel = Math.min(inclusionBlock.header.level + levelDiff, inclusionBlock.header.level + MAX_BRANCH_ANCESTORS); const blocks = new Set(yield this.context.readProvider.getLiveBlocks(tipBlockLevel)); return blocks.has(inclusionBlock.hash); }); } confirmationObservable(confirmations) { if (typeof confirmations !== 'undefined' && confirmations < 1) { throw new errors_1.InvalidConfirmationCountError(confirmations); } const { defaultConfirmationCount } = this.context.config; const conf = confirmations !== undefined ? confirmations : defaultConfirmationCount; if (conf === undefined) { throw new errors_2.ConfirmationUndefinedError(); } return (0, rxjs_1.combineLatest)([this._includedInBlock, this.newHead$]).pipe((0, operators_1.distinctUntilChanged)(([, previousHead], [, newHead]) => { return previousHead.hash === newHead.hash; }), (0, operators_1.map)(([foundAtBlock, head]) => { return { block: head, expectedConfirmation: conf, currentConfirmation: head.header.level - foundAtBlock.header.level + 1, completed: head.header.level - foundAtBlock.header.level >= conf - 1, isInCurrentBranch: () => this.isInCurrentBranch(head.hash), }; }), (0, operators_1.takeWhile)(({ completed }) => !completed, true)); } /** * * @param confirmations [0] Number of confirmation to wait for */ confirmation(confirmations) { return this.confirmationObservable(confirmations).toPromise(); } } exports.WalletOperation = WalletOperation;