@gear-js/api
Version:
A JavaScript library that provides functionality to connect GEAR Component APIs.
145 lines (141 loc) • 5.84 kB
JavaScript
;
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;