@taquito/taquito
Version:
High level functionality that builds upon the other packages in the Tezos Typescript Library Suite.
125 lines • 6.08 kB
JavaScript
;
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.OnChainView = void 0;
const utils_1 = require("@taquito/utils");
const errors_1 = require("../errors");
const core_1 = require("@taquito/core");
class OnChainView {
constructor(_rpc, _readProvider, _contractAddress, _smartContractViewSchema, _contractStorageType, _args = 'Unit') {
this._rpc = _rpc;
this._readProvider = _readProvider;
this._contractAddress = _contractAddress;
this._smartContractViewSchema = _smartContractViewSchema;
this._contractStorageType = _contractStorageType;
this._args = _args;
}
/**
* @description Get the signature of the smart contract view
*/
getSignature() {
return {
parameter: this._smartContractViewSchema.extractArgsSchema(),
result: this._smartContractViewSchema.extractResultSchema(),
};
}
/**
* @description Get the result of the view simulation
* @param executionContext.source the public key hash of the account who initialized this view execution.
* @param executionContext.viewCaller the contract address which is the caller of view.
*/
executeView(executionContext) {
return __awaiter(this, void 0, void 0, function* () {
this.verifyContextExecution(executionContext);
const chainId = yield this._readProvider.getChainId();
const viewArgs = this.transformArgsToMichelson();
const scriptView = {
contract: this._contractAddress,
view: this._smartContractViewSchema.viewName,
input: viewArgs,
chain_id: chainId,
source: executionContext.viewCaller,
};
if (executionContext.source) {
scriptView.payer = executionContext.source;
}
return this.executeViewAndDecodeResult(scriptView);
});
}
verifyContextExecution(executionContext) {
if (executionContext.source &&
utils_1.validateAddress(executionContext.source) !== utils_1.ValidationResult.VALID) {
throw new errors_1.InvalidViewSimulationContext(`The source account who initialized the view execution is invalid: ${executionContext.source}.`);
}
if (!executionContext.viewCaller ||
utils_1.validateAddress(executionContext.viewCaller) !== utils_1.ValidationResult.VALID) {
throw new errors_1.InvalidViewSimulationContext(`The contract which is the caller of view is invalid: ${executionContext.viewCaller}.`);
}
}
transformArgsToMichelson() {
try {
return this._smartContractViewSchema.encodeViewArgs(this._args);
}
catch (error) {
throw new core_1.InvalidViewParameterError(this._smartContractViewSchema.viewName, this.getSignature(), this._args, error);
}
}
/**
* @description Loops through the view's instructions and replace BALANCE, SENDER, SELF_ADDRESS and AMOUNT with Michelson expressions that match the current context, if applicable.
*
* Certain specific instructions have different semantics in view:
* BALANCE represents the current amount of mutez held by the contract where view is;
* SENDER represents the contract which is the caller of view;
* SELF_ADDRESS represents the contract where view is;
* AMOUNT is always 0 mutez.
*
*/
adaptViewCodeToContext(instructions, viewCaller, contractBalance) {
const instructionsToReplace = {
BALANCE: [{ prim: 'PUSH', args: [{ prim: 'mutez' }, { int: contractBalance }] }],
SENDER: [{ prim: 'PUSH', args: [{ prim: 'address' }, { string: viewCaller }] }],
SELF_ADDRESS: [
{ prim: 'PUSH', args: [{ prim: 'address' }, { string: this._contractAddress }] },
],
AMOUNT: [{ prim: 'PUSH', args: [{ prim: 'mutez' }, { int: '0' }] }],
};
instructions.forEach((inst, i) => {
if (inst.prim in instructionsToReplace) {
instructions[i] = Object(instructionsToReplace)[inst.prim];
}
if (inst.args && inst.args.length !== 0) {
this.adaptViewCodeToContext(inst.args, viewCaller, contractBalance);
}
else if (Array.isArray(inst)) {
this.adaptViewCodeToContext(inst, viewCaller, contractBalance);
}
});
return instructions;
}
executeViewAndDecodeResult(viewScript) {
return __awaiter(this, void 0, void 0, function* () {
let storage;
try {
storage = (yield this._rpc.runScriptView(viewScript))
.data;
}
catch (error) {
const failWith = errors_1.validateAndExtractFailwith(error);
throw failWith
? new errors_1.ViewSimulationError(`The simulation of the on-chain view named ${this._smartContractViewSchema.viewName} failed with: ${JSON.stringify(failWith)}`, this._smartContractViewSchema.viewName, failWith, error)
: error;
}
return this._smartContractViewSchema.decodeViewResult(storage);
});
}
}
exports.OnChainView = OnChainView;
//# sourceMappingURL=contract-on-chain-view.js.map