@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
JavaScript
"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;