UNPKG

@taquito/taquito

Version:

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

552 lines 30.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.RpcContractProvider = void 0; const http_utils_1 = require("@taquito/http-utils"); const michelson_encoder_1 = require("@taquito/michelson-encoder"); const rpc_1 = require("@taquito/rpc"); const utils_1 = require("@taquito/utils"); const core_1 = require("@taquito/core"); const rpc_batch_provider_1 = require("../batch/rpc-batch-provider"); const delegate_operation_1 = require("../operations/delegate-operation"); const origination_operation_1 = require("../operations/origination-operation"); const register_global_constant_operation_1 = require("../operations/register-global-constant-operation"); const reveal_operation_1 = require("../operations/reveal-operation"); const transaction_operation_1 = require("../operations/transaction-operation"); const contract_1 = require("./contract"); const errors_1 = require("./errors"); const semantic_1 = require("./semantic"); const transfer_ticket_operation_1 = require("../operations/transfer-ticket-operation"); const increase_paid_storage_operation_1 = require("../operations/increase-paid-storage-operation"); const ballot_operation_1 = require("../operations/ballot-operation"); const drain_delegate_operation_1 = require("../operations/drain-delegate-operation"); const proposals_operation_1 = require("../operations/proposals-operation"); const update_consensus_key_operation_1 = require("../operations/update-consensus-key-operation"); const smart_rollup_add_messages_operation_1 = require("../operations/smart-rollup-add-messages-operation"); const smart_rollup_originate_operation_1 = require("../operations/smart-rollup-originate-operation"); const provider_1 = require("../provider"); const prepare_1 = require("../prepare"); class RpcContractProvider extends provider_1.Provider { constructor(context, estimator) { super(context); this.estimator = estimator; this.contractProviderTypeSymbol = Symbol.for('taquito-contract-provider-type-symbol'); this.prepare = new prepare_1.PrepareProvider(this.context); } /** * * @description Return a well formatted json object of the contract storage * * @param contract contract address you want to get the storage from * @param schema optional schema can either be the contract script rpc response or a michelson-encoder schema * @throws {@link InvalidContractAddressError} * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-context-contracts-contract-id-script */ getStorage(contract, schema) { return __awaiter(this, void 0, void 0, function* () { const contractValidation = utils_1.validateContractAddress(contract); if (contractValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidContractAddressError(contract, utils_1.invalidErrorDetail(contractValidation)); } const script = yield this.context.readProvider.getScript(contract, 'head'); if (!schema) { schema = script; } let contractSchema; if (michelson_encoder_1.Schema.isSchema(schema)) { contractSchema = schema; } else { contractSchema = michelson_encoder_1.Schema.fromRPCResponse({ script: schema }); } return contractSchema.Execute(script.storage, semantic_1.smartContractAbstractionSemantic(this)); // Cast into T because only the caller can know the true type of the storage }); } /** * * @description Return a well formatted json object of the contract big map storage * * @param contract contract address you want to get the storage from * @param key contract big map key to fetch value from * @param schema optional schema can either be the contract script rpc response or a michelson-encoder schema * @throws {@link InvalidContractAddressError} * @deprecated Deprecated in favor of getBigMapKeyByID * * @see https://tezos.gitlab.io/api/rpc.html#post-block-id-context-contracts-contract-id-big-map-get */ getBigMapKey(contract, key, schema) { return __awaiter(this, void 0, void 0, function* () { const contractValidation = utils_1.validateContractAddress(contract); if (contractValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidContractAddressError(contract, utils_1.invalidErrorDetail(contractValidation)); } if (!schema) { schema = (yield this.rpc.getContract(contract)).script; } let contractSchema; if (michelson_encoder_1.Schema.isSchema(schema)) { contractSchema = schema; } else { contractSchema = michelson_encoder_1.Schema.fromRPCResponse({ script: schema }); } const encodedKey = contractSchema.EncodeBigMapKey(key); const val = yield this.rpc.getBigMapKey(contract, encodedKey); return contractSchema.ExecuteOnBigMapValue(val); // Cast into T because only the caller can know the true type of the storage }); } /** * * @description Return a well formatted json object of a big map value * * @param id Big Map ID * @param keyToEncode key to query (will be encoded properly according to the schema) * @param schema Big Map schema (can be determined using your contract type) * @param block optional block level to fetch the values from * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-context-big-maps-big-map-id-script-expr */ getBigMapKeyByID(id, keyToEncode, schema, block) { return __awaiter(this, void 0, void 0, function* () { const { key, type } = schema.EncodeBigMapKey(keyToEncode); const { packed } = yield this.context.packer.packData({ data: key, type }); const encodedExpr = utils_1.encodeExpr(packed); const bigMapValue = block ? yield this.context.readProvider.getBigMapValue({ id: id.toString(), expr: encodedExpr }, block) : yield this.context.readProvider.getBigMapValue({ id: id.toString(), expr: encodedExpr }, 'head'); return schema.ExecuteOnBigMapValue(bigMapValue, semantic_1.smartContractAbstractionSemantic(this)); }); } /** * * @description Fetch multiple values in a big map * All values will be fetched on the same block level. If a block is specified in the request, the values will be fetched at it. * Otherwise, a first request will be done to the node to fetch the level of the head and all values will be fetched at this level. * If one of the keys does not exist in the big map, its value will be set to undefined. * * @param id Big Map ID * @param keys Array of keys to query (will be encoded properly according to the schema) * @param schema Big Map schema (can be determined using your contract type) * @param block optional block level to fetch the values from * @param batchSize optional batch size representing the number of requests to execute in parallel * @returns A MichelsonMap containing the keys queried in the big map and their value in a well-formatted JSON object format * */ getBigMapKeysByID(id, keys, schema, block, batchSize = 5) { return __awaiter(this, void 0, void 0, function* () { const level = yield this.getBlockForRequest(keys, block); const bigMapValues = new michelson_encoder_1.MichelsonMap(); // Execute batch of promises in series let position = 0; let results = []; while (position < keys.length) { const keysBatch = keys.slice(position, position + batchSize); const batch = keysBatch.map((keyToEncode) => this.getBigMapValueOrUndefined(keyToEncode, id, schema, level)); results = [...results, ...(yield Promise.all(batch))]; position += batchSize; } for (let i = 0; i < results.length; i++) { bigMapValues.set(keys[i], results[i]); } return bigMapValues; }); } getBlockForRequest(keys, block) { return __awaiter(this, void 0, void 0, function* () { return keys.length === 1 || typeof block !== 'undefined' ? block : yield this.context.readProvider.getBlockLevel('head'); }); } getBigMapValueOrUndefined(keyToEncode, id, schema, level) { return __awaiter(this, void 0, void 0, function* () { try { return yield this.getBigMapKeyByID(id, keyToEncode, schema, level); } catch (ex) { if (ex instanceof http_utils_1.HttpResponseError && ex.status === http_utils_1.STATUS_CODE.NOT_FOUND) { return; } else { throw ex; } } }); } /** * * @description Return a well formatted json object of a sapling state * * @param id Sapling state ID * @param block optional block level to fetch the value from * */ getSaplingDiffByID(id, block) { return __awaiter(this, void 0, void 0, function* () { const saplingState = block ? yield this.context.readProvider.getSaplingDiffById({ id: id.toString() }, block) : yield this.context.readProvider.getSaplingDiffById({ id: id.toString() }, 'head'); return saplingState; }); } /** * * @description Originate a new contract according to the script in parameters. Will sign and inject an operation using the current context * * @returns An operation handle with the result from the rpc node * * @warn You cannot specify storage and init at the same time (use init to pass the raw michelson representation of storage) * * @param OriginationOperation Originate operation parameter */ originate(params) { return __awaiter(this, void 0, void 0, function* () { const estimate = yield this.estimate(params, this.estimator.originate.bind(this.estimator)); const preparedOrigination = yield this.prepare.originate(Object.assign(Object.assign({}, params), estimate)); const content = preparedOrigination.opOb.contents.find((op) => op.kind === rpc_1.OpKind.ORIGINATION); const forgedOrigination = yield this.forge(preparedOrigination); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(forgedOrigination); return new origination_operation_1.OriginationOperation(hash, content, forgedBytes, opResponse, context, this); }); } /** * * @description Set the delegate for a contract. Will sign and inject an operation using the current context * * @returns An operation handle with the result from the rpc node * * @param SetDelegate operation parameter */ setDelegate(params) { var _a; return __awaiter(this, void 0, void 0, function* () { const sourceValidation = utils_1.validateAddress(params.source); if (params.source && sourceValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.source, utils_1.invalidErrorDetail(sourceValidation)); } const delegateValidation = utils_1.validateAddress((_a = params.delegate) !== null && _a !== void 0 ? _a : ''); if (params.delegate && delegateValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.delegate, utils_1.invalidErrorDetail(delegateValidation)); } // Since babylon delegation source cannot smart contract if (/kt1/i.test(params.source)) { throw new errors_1.InvalidDelegationSource(params.source); } const publicKeyHash = yield this.signer.publicKeyHash(); const sourceOrDefault = params.source || publicKeyHash; const estimate = yield this.estimate(params, this.estimator.setDelegate.bind(this.estimator)); const preparedDelegation = yield this.prepare.delegation(Object.assign(Object.assign({}, params), estimate)); const content = preparedDelegation.opOb.contents.find((op) => op.kind === rpc_1.OpKind.DELEGATION); const opBytes = yield this.forge(preparedDelegation); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new delegate_operation_1.DelegateOperation(hash, content, sourceOrDefault, forgedBytes, opResponse, context); }); } /** * * @description Register the current address as delegate. Will sign and inject an operation using the current context * * @returns An operation handle with the result from the rpc node * * @param RegisterDelegate operation parameter */ registerDelegate(params) { return __awaiter(this, void 0, void 0, function* () { const estimate = yield this.estimate(params, this.estimator.registerDelegate.bind(this.estimator)); const source = yield this.signer.publicKeyHash(); const prepared = yield this.prepare.registerDelegate(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.DELEGATION); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new delegate_operation_1.DelegateOperation(hash, content, source, forgedBytes, opResponse, context); }); } /** * * @description Transfer tz from current address to a specific address. Will sign and inject an operation using the current context * * @returns An operation handle with the result from the rpc node * * @param Transfer operation parameter */ transfer(params) { var _a; return __awaiter(this, void 0, void 0, function* () { const toValidation = utils_1.validateAddress(params.to); if (toValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.to, utils_1.invalidErrorDetail(toValidation)); } const sourceValidation = utils_1.validateAddress((_a = params.source) !== null && _a !== void 0 ? _a : ''); if (params.source && sourceValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.source, utils_1.invalidErrorDetail(sourceValidation)); } const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.transfer.bind(this.estimator)); const source = params.source || publicKeyHash; const prepared = yield this.prepare.transaction(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.TRANSACTION); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new transaction_operation_1.TransactionOperation(hash, content, source, forgedBytes, opResponse, context); }); } /** * * @description Transfer Tickets to a smart contract address * * @returns An operation handle with the result from the rpc node * * @param TransferTicketParams operation parameter */ transferTicket(params) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const destinationValidation = utils_1.validateAddress(params.destination); if (destinationValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.destination, utils_1.invalidErrorDetail(destinationValidation)); } const srouceValidation = utils_1.validateAddress((_a = params.source) !== null && _a !== void 0 ? _a : ''); if (params.source && srouceValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.source, utils_1.invalidErrorDetail(srouceValidation)); } const publicKeyHash = yield this.signer.publicKeyHash(); const source = (_b = params.source) !== null && _b !== void 0 ? _b : publicKeyHash; const estimate = yield this.estimate(params, this.estimator.transferTicket.bind(this.estimator)); const prepared = yield this.prepare.transferTicket(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.TRANSFER_TICKET); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new transfer_ticket_operation_1.TransferTicketOperation(hash, content, source, forgedBytes, opResponse, context); }); } /** * * @description Reveal the current address. Will throw an error if the address is already revealed. * * @returns An operation handle with the result from the rpc node * * @param RevealParams operation parameter */ reveal(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimateReveal = yield this.estimator.reveal(params); if (estimateReveal) { const estimated = yield this.estimate(params, () => __awaiter(this, void 0, void 0, function* () { return estimateReveal; })); const prepared = yield this.prepare.reveal(Object.assign(Object.assign({}, params), estimated)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.REVEAL); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new reveal_operation_1.RevealOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); } else { throw new errors_1.RevealOperationError(`The publicKeyHash '${publicKeyHash}' has already been revealed.`); } }); } /** * * @description Register a Micheline expression in a global table of constants. Will sign and inject an operation using the current context * * @returns An operation handle with the result from the rpc node * * @param params registerGlobalConstant operation parameter */ registerGlobalConstant(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.registerGlobalConstant.bind(this.estimator)); const prepared = yield this.prepare.registerGlobalConstant(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.REGISTER_GLOBAL_CONSTANT); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new register_global_constant_operation_1.RegisterGlobalConstantOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * * @description Increase the paid storage of a smart contract * * @returns An operation handle with the result from the rpc node * * @param params increasePaidStorage operation parameter */ increasePaidStorage(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.increasePaidStorage.bind(this.estimator)); const prepared = yield this.prepare.increasePaidStorage(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.INCREASE_PAID_STORAGE); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new increase_paid_storage_operation_1.IncreasePaidStorageOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * * @description Transfers the spendable balance of the delegate to destination when consensus_key is the active consensus key of delegate * * @returns An operation handle with the result from the rpc node * * @param params drainDelegate operation parameter */ drainDelegate(params) { return __awaiter(this, void 0, void 0, function* () { const prepared = yield this.prepare.drainDelegate(params); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.DRAIN_DELEGATE); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new drain_delegate_operation_1.DrainDelegateOperation(hash, content, forgedBytes, opResponse, context); }); } /** * * @description Submit a ballot vote to a specified proposal * * @returns An operation handle with the result from the rpc node * * @param BallotParams Ballot operation parameter */ ballot(params) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const sourceValidation = utils_1.validateAddress((_a = params.source) !== null && _a !== void 0 ? _a : ''); if (params.source && sourceValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.source, utils_1.invalidErrorDetail(sourceValidation)); } const source = (_b = params.source) !== null && _b !== void 0 ? _b : publicKeyHash; const prepared = yield this.prepare.ballot(Object.assign(Object.assign({}, params), { source })); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.BALLOT); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new ballot_operation_1.BallotOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * * @description Submit or upvote a proposal during the Proposal period * * @returns An operation handle with the result from the rpc node * * @param ProposalsParams Proposals operation parameter */ proposals(params) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const sourceValidation = utils_1.validateAddress((_a = params.source) !== null && _a !== void 0 ? _a : ''); if (params.source && sourceValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidAddressError(params.source, utils_1.invalidErrorDetail(sourceValidation)); } const source = (_b = params.source) !== null && _b !== void 0 ? _b : publicKeyHash; const prepared = yield this.prepare.proposals(Object.assign(Object.assign({}, params), { source })); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.PROPOSALS); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new proposals_operation_1.ProposalsOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * * @description Updates the consensus key of the baker to public_key starting from the current cycle plus PRESERVED_CYCLES + 1 * * @returns An operation handle with the result from the rpc node * * @param UpdateConsensusKeyParams */ updateConsensusKey(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.updateConsensusKey.bind(this.estimator)); const prepared = yield this.prepare.updateConsensusKey(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.UPDATE_CONSENSUS_KEY); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new update_consensus_key_operation_1.UpdateConsensusKeyOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * @description Adds messages to the rollup inbox that can be executed/claimed after it gets cemented * @param SmartRollupAddMessagesParams * @returns An operation handle with results from the RPC node */ smartRollupAddMessages(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.smartRollupAddMessages.bind(this.estimator)); const prepared = yield this.prepare.smartRollupAddMessages(Object.assign(Object.assign({}, params), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.SMART_ROLLUP_ADD_MESSAGES); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new smart_rollup_add_messages_operation_1.SmartRollupAddMessagesOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * @description Creates a smart rollup originate operation * @param SmartRollupOriginateParams * @returns An operation handle with results from the RPC node */ smartRollupOriginate(params) { return __awaiter(this, void 0, void 0, function* () { const publicKeyHash = yield this.signer.publicKeyHash(); const estimate = yield this.estimate(params, this.estimator.smartRollupOriginate.bind(this.estimator)); const originationProof = yield this.rpc.getOriginationProof({ kind: params.pvmKind, kernel: params.kernel, }); const completeParams = Object.assign(Object.assign({}, params), { originationProof }); const prepared = yield this.prepare.smartRollupOriginate(Object.assign(Object.assign({}, completeParams), estimate)); const content = prepared.opOb.contents.find((op) => op.kind === rpc_1.OpKind.SMART_ROLLUP_ORIGINATE); const opBytes = yield this.forge(prepared); const { hash, context, forgedBytes, opResponse } = yield this.signAndInject(opBytes); return new smart_rollup_originate_operation_1.SmartRollupOriginateOperation(hash, content, publicKeyHash, forgedBytes, opResponse, context); }); } /** * * @description Create an smart contract abstraction for the address specified. * * @param address Smart contract address * @throws {@link InvalidContractAddressError} */ at(address, contractAbstractionComposer = (x) => x) { return __awaiter(this, void 0, void 0, function* () { const addressValidation = utils_1.validateContractAddress(address); if (addressValidation !== utils_1.ValidationResult.VALID) { throw new core_1.InvalidContractAddressError(address, utils_1.invalidErrorDetail(addressValidation)); } const rpc = this.context.withExtensions().rpc; const readProvider = this.context.withExtensions().readProvider; const script = yield readProvider.getScript(address, 'head'); const entrypoints = yield readProvider.getEntrypoints(address); const abs = new contract_1.ContractAbstraction(address, script, this, this, entrypoints, rpc, readProvider); return contractAbstractionComposer(abs, this.context); }); } /** * * @description Batch a group of operation together. Operations will be applied in the order in which they are added to the batch * * @returns A batch object from which we can add more operation or send a command to execute the batch * * @param params List of operation to batch together */ batch(params) { const batch = new rpc_batch_provider_1.OperationBatch(this.context, this.estimator); if (Array.isArray(params)) { batch.with(params); } return batch; } } exports.RpcContractProvider = RpcContractProvider; //# sourceMappingURL=rpc-contract-provider.js.map