UNPKG

@gear-js/api

Version:

A JavaScript library that provides functionality to connect GEAR Component APIs.

145 lines (141 loc) 5.84 kB
'use strict'; var rxjs = require('rxjs'); var message_errors = require('../errors/message.errors.js'); require('@polkadot/util'); require('../utils/generate.js'); var validate = require('../utils/validate.js'); var address = require('../utils/address.js'); require('@polkadot/util-crypto'); var createPayload = require('../utils/create-payload.js'); var getExtrinsic = require('../utils/getExtrinsic.js'); var Transaction = require('./Transaction.js'); class GearMessage extends Transaction.GearTransaction { /** * ## Send Message * @param message * @param metaOrHexRegistry Metadata * @param typeIndexOrTypeName type index in registry or type name * @returns Submitable result */ send({ destination, value, gasLimit, payload, keepAlive }, metaOrHexRegistry, typeIndexOrTypeName) { validate.validateValue(value, this._api); validate.validateGasLimit(gasLimit, this._api); const _payload = createPayload.encodePayload(payload, metaOrHexRegistry, 'handle', typeIndexOrTypeName); try { const txArgs = [destination, _payload, gasLimit, value || 0, keepAlive || true]; this.extrinsic = getExtrinsic.getExtrinsic(this._api, 'gear', 'sendMessage', txArgs); return this.extrinsic; } catch (error) { throw new message_errors.SendMessageError(error.message); } } /** * Sends reply message * @param args Message parameters * @param metaOrHexRegistry Metadata * @param typeIndexOrTypeName type index in registry or type name * @returns Submittable result */ async sendReply({ value, gasLimit, replyToId, payload, account, keepAlive }, metaOrHexRegistry, typeIndexOrTypeName) { validate.validateValue(value, this._api); validate.validateGasLimit(gasLimit, this._api); if (account) { await validate.validateMailboxItem(account, replyToId, this._api); } const _payload = createPayload.encodePayload(payload, metaOrHexRegistry, 'reply', typeIndexOrTypeName); try { const txArgs = [replyToId, _payload, gasLimit, value || 0, keepAlive || true]; this.extrinsic = getExtrinsic.getExtrinsic(this._api, 'gear', 'sendReply', txArgs); return this.extrinsic; } catch (_) { throw new message_errors.SendReplyError(); } } /** * ## Get event with reply message * @param msgId - id of sent message * @param txBlock - number or hash of block where the message was sent * @returns UserMessageSent event */ async getReplyEvent(programId, msgId, txBlock) { let unsub; const replyEvent = new Promise((resolve) => { unsub = this._api.gearEvents.subscribeToGearEvent('UserMessageSent', (event) => { if (event.data.message.source.eq(programId) === false) return; if (msgId === null) { resolve(event); } if (event.data.message.details.isSome && event.data.message.details.unwrap().to.toHex() === msgId) { resolve(event); } }, txBlock); }); (await unsub)(); return replyEvent; } /** * @deprecated Use `getReplyEvent` instead */ listenToReplies(programId, bufferSize = 5) { let unsub; const subject = new rxjs.ReplaySubject(bufferSize); this._api.gearEvents .subscribeToGearEvent('UserMessageSent', ({ data }) => { if (data.message.source.eq(programId)) { if (data.message.details.isSome) { data.message.details.unwrap().to.toHex(); { subject.next([data.message.details.unwrap().to.toHex(), data]); } } } }) .then((result) => { unsub = result; }); return (messageId) => { return new Promise((resolve) => { subject.subscribe({ next: ([id, data]) => { if (id === messageId) { subject.complete(); unsub(); resolve(data); } }, }); }); }; } /** * ## Send message to the program and get the reply. * This method is immutable and doesn't send any extrinsic. * @param params Message parameters * @param meta (optional) Program metadata obtained using `ProgramMetadata.from` method. * @param typeIndexOrTypeName (optional) Index of type in the registry. If not specified the type index from `meta.handle.input` will be used instead. * @returns Reply info structure * * @example * ```javascript * const programId = '0x..'; * const origin = '0x...'; * const meta = ProgramMetadata.from('0x...'); * const result = await api.message.calculateReply({ * origin, * destination: programId, * payload: { myPayload: [] }, * value: 0 * }, meta); * * console.log(result.toJSON()); * console.log('reply payload:', meta.createType(meta.types.handle.output, result.payload).toJSON()); */ async calculateReply({ payload, origin, destination, value, gasLimit, at }, meta, typeIndexOrTypeName) { const _payload = createPayload.encodePayload(payload, meta, 'handle', typeIndexOrTypeName); return await this._api.rpc.gear.calculateReplyForHandle(address.decodeAddress(origin), destination, _payload, gasLimit || this._api.blockGasLimit.toBigInt(), value || 0, at || null); } } exports.GearMessage = GearMessage;