UNPKG

@mavrykdynamics/taquito

Version:

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

193 lines (192 loc) 11.6 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.ContractAbstraction = exports.ContractView = exports.DEFAULT_SMART_CONTRACT_METHOD_NAME = void 0; const taquito_michelson_encoder_1 = require("@mavrykdynamics/taquito-michelson-encoder"); const taquito_utils_1 = require("@mavrykdynamics/taquito-utils"); const contract_method_factory_1 = require("./contract-methods/contract-method-factory"); const errors_1 = require("./errors"); const taquito_core_1 = require("@mavrykdynamics/taquito-core"); exports.DEFAULT_SMART_CONTRACT_METHOD_NAME = 'default'; /** * @description Utility class to retrieve data from a smart contract's storage without incurring fees via a contract's view method */ class ContractView { constructor(currentContract, name, callbackParametersSchema, parameterSchema, args, rpc, readProvider) { this.currentContract = currentContract; this.name = name; this.callbackParametersSchema = callbackParametersSchema; this.parameterSchema = parameterSchema; this.args = args; this.rpc = rpc; this.readProvider = readProvider; } read(chainId) { return __awaiter(this, void 0, void 0, function* () { const chainIdValidation = (0, taquito_utils_1.validateChain)(chainId !== null && chainId !== void 0 ? chainId : ''); if ((0, taquito_utils_1.validateContractAddress)(chainId !== null && chainId !== void 0 ? chainId : '') == taquito_utils_1.ValidationResult.VALID) { throw new taquito_core_1.DeprecationError(`Since version 12, the lambda view no longer depends on a lambda contract. The read method no longer accepts a contract address as a parameter.`); } else if (chainId && chainIdValidation !== taquito_utils_1.ValidationResult.VALID) { throw new taquito_core_1.InvalidChainIdError(chainId, (0, taquito_utils_1.invalidDetail)(chainIdValidation)); } const arg = this.parameterSchema.Encode(...this.args); const result = yield this.rpc.runView({ contract: this.currentContract.address, entrypoint: this.name, input: arg, chain_id: chainId ? chainId : yield this.readProvider.getChainId(), }); return this.callbackParametersSchema.Execute(result.data); }); } } exports.ContractView = ContractView; const validateArgs = (args, schema, name) => { const sigs = schema.ExtractSignatures(); if (!sigs.find((x) => x.length === args.length)) { throw new errors_1.InvalidParameterError(name, sigs, args); } }; // lambda view tzip4 const isView = (entrypoint) => { let isView = false; if ('prim' in entrypoint && entrypoint.prim === 'pair' && entrypoint.args) { const lastElement = entrypoint.args[entrypoint.args.length - 1]; if ('prim' in lastElement && lastElement.prim === 'contract') { isView = true; } } return isView; }; /** * @description Smart contract abstraction */ class ContractAbstraction { constructor(address, script, provider, storageProvider, entrypoints, rpc, readProvider) { this.address = address; this.script = script; this.storageProvider = storageProvider; this.entrypoints = entrypoints; this.rpc = rpc; this.readProvider = readProvider; /** * @deprecated use methodsObject instead, flat params of methods can't sufficiently represent all Michelson values * @description Contains methods that are implemented by the target Mavryk Smart Contract, and offers the user to call the Smart Contract methods as if they were native TS/JS methods. * NB: if the contract contains annotation it will include named properties; if not it will be indexed by a number. */ this.methods = {}; /** * @description Contains methods that are implemented by the target Mavryk Smart Contract, and offers the user to call the Smart Contract methods as if they were native TS/JS methods. * `methodsObject` serves the exact same purpose as the `methods` member. The difference is that it allows passing the parameter in an object format when calling the smart contract method (instead of the flattened representation) * NB: if the contract contains annotation it will include named properties; if not it will be indexed by a number. * */ this.methodsObject = {}; /** * @description Contains lamda views (tzip4) that are implemented by the target Mavryk Smart Contract, and offers the user to call the lambda views as if they were native TS/JS methods. * NB: These are the view defined in the tzip4 standard, not the views introduced by the Hangzhou protocol. */ this.views = {}; /** * @description Contains on-chain views that are defined by the target Mavryk Smart Contract, and offers the user to simulate the views execution as if they were native TS/JS methods. * NB: the expected format for the parameter when calling a smart contract view is the object format (same format as for the storage) and not the flattened representation. * */ this.contractViews = {}; this.contractMethodFactory = new contract_method_factory_1.ContractMethodFactory(provider, address); this.schema = taquito_michelson_encoder_1.Schema.fromRPCResponse({ script: this.script }); this.parameterSchema = taquito_michelson_encoder_1.ParameterSchema.fromRPCResponse({ script: this.script }); this.viewSchema = taquito_michelson_encoder_1.ViewSchema.fromRPCResponse({ script: this.script }); if (this.viewSchema.length !== 0) { this._initializeOnChainViews(this, rpc, this.readProvider, this.viewSchema); } this.eventSchema = taquito_michelson_encoder_1.EventSchema.fromRPCResponse({ script: this.script }); this._initializeMethods(this, this.entrypoints.entrypoints, this.rpc, this.readProvider); } _initializeMethods(currentContract, entrypoints, rpc, readProvider) { const parameterSchema = this.parameterSchema; const keys = Object.keys(entrypoints); if (parameterSchema.isMultipleEntryPoint) { keys.forEach((smartContractMethodName) => { const smartContractMethodSchema = new taquito_michelson_encoder_1.ParameterSchema(entrypoints[smartContractMethodName]); this.methods[smartContractMethodName] = function (...args) { return currentContract.contractMethodFactory.createContractMethodFlatParams(smartContractMethodSchema, smartContractMethodName, args); }; this.methodsObject[smartContractMethodName] = function (args) { return currentContract.contractMethodFactory.createContractMethodObjectParam(smartContractMethodSchema, smartContractMethodName, args); }; if (isView(entrypoints[smartContractMethodName])) { const view = function (...args) { const entrypointParamWithoutCallback = entrypoints[smartContractMethodName] .args[0]; const smartContractMethodSchemaWithoutCallback = new taquito_michelson_encoder_1.ParameterSchema(entrypointParamWithoutCallback); const parametersCallback = entrypoints[smartContractMethodName].args[1] .args[0]; const smartContractMethodCallbackSchema = new taquito_michelson_encoder_1.ParameterSchema(parametersCallback); validateArgs(args, smartContractMethodSchemaWithoutCallback, smartContractMethodName); return new ContractView(currentContract, smartContractMethodName, smartContractMethodCallbackSchema, smartContractMethodSchemaWithoutCallback, args, rpc, readProvider); }; this.views[smartContractMethodName] = view; } }); // Deal with methods with no annotations which were not discovered by the RPC endpoint // Methods with no annotations are discovered using parameter schema const anonymousMethods = Object.keys(parameterSchema.ExtractSchema()).filter((key) => Object.keys(entrypoints).indexOf(key) === -1); anonymousMethods.forEach((smartContractMethodName) => { this.methods[smartContractMethodName] = function (...args) { return currentContract.contractMethodFactory.createContractMethodFlatParams(parameterSchema, smartContractMethodName, args, false, true); }; this.methodsObject[smartContractMethodName] = function (args) { return currentContract.contractMethodFactory.createContractMethodObjectParam(parameterSchema, smartContractMethodName, args, false, true); }; }); } else { const smartContractMethodSchema = this.parameterSchema; this.methods[exports.DEFAULT_SMART_CONTRACT_METHOD_NAME] = function (...args) { return currentContract.contractMethodFactory.createContractMethodFlatParams(smartContractMethodSchema, exports.DEFAULT_SMART_CONTRACT_METHOD_NAME, args, false); }; this.methodsObject[exports.DEFAULT_SMART_CONTRACT_METHOD_NAME] = function (args) { return currentContract.contractMethodFactory.createContractMethodObjectParam(smartContractMethodSchema, exports.DEFAULT_SMART_CONTRACT_METHOD_NAME, args, false); }; } } _initializeOnChainViews(currentContract, rpc, readProvider, allContractViews) { const storageType = this.schema.val; allContractViews.forEach((viewSchema) => { this.contractViews[viewSchema.viewName] = function (args) { return currentContract.contractMethodFactory.createContractViewObjectParam(rpc, readProvider, viewSchema, storageType, args); }; }); } /** * @description Return a friendly representation of the smart contract storage */ storage() { return this.storageProvider.getStorage(this.address, this.schema); } /** * * @description Return a friendly representation of the smart contract big map value * * @param key BigMap key to fetch * * @deprecated getBigMapKey has been deprecated in favor of getBigMapKeyByID * * @see https://protocol.mavryk.org/api/rpc.html#post-block-id-context-contracts-contract-id-big-map-get */ bigMap(key) { return this.storageProvider.getBigMapKey(this.address, key, this.schema); } } exports.ContractAbstraction = ContractAbstraction;