@aeternity/aepp-sdk
Version:
SDK for the æternity blockchain
183 lines (176 loc) • 6.03 kB
JavaScript
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
import { buildTxAsync } from '../tx/builder/index.js';
import { Tag } from '../tx/builder/constants.js';
import { LogicError, UnexpectedTsError } from '../utils/errors.js';
import { decode, encode, Encoding } from '../utils/encoder.js';
import { _getPollInterval } from '../chain.js';
import { sendTransaction } from '../send-transaction.js';
import OracleBase from './OracleBase.js';
/**
* @category oracle
*/
/**
* @category oracle
*/
/**
* @category oracle
*/
var _handleQueriesPromise = /*#__PURE__*/new WeakMap();
/**
* @category oracle
*/
export default class Oracle extends OracleBase {
/**
* @param account - Account to use as oracle
* @param options - Options object
*/
constructor(account, options) {
super(encode(decode(account.address), Encoding.OracleAddress), options);
_classPrivateFieldInitSpec(this, _handleQueriesPromise, void 0);
this.account = account;
this.options = options;
}
// TODO: support abiVersion other than 0
/**
* Register oracle
* @param queryFormat - Format of query
* @param responseFormat - Format of query response
* @param options - Options object
*/
async register(queryFormat, responseFormat, options = {}) {
const opt = {
...this.options,
...options
};
const oracleRegisterTx = await buildTxAsync({
_isInternalBuild: true,
...opt,
tag: Tag.OracleRegisterTx,
accountId: this.account.address,
queryFormat,
responseFormat
});
return sendTransaction(oracleRegisterTx, {
...opt,
onAccount: this.account
});
}
/**
* Extend oracle ttl
* @param options - Options object
*/
async extendTtl(options = {}) {
const opt = {
...this.options,
...options
};
const oracleExtendTx = await buildTxAsync({
_isInternalBuild: true,
...opt,
tag: Tag.OracleExtendTx,
oracleId: this.address
});
return sendTransaction(oracleExtendTx, {
...opt,
onAccount: this.account
});
}
/**
* Poll for oracle queries
* @param onQuery - OnQuery callback
* @param options - Options object
* @param options.interval - Poll interval (default: 5000)
* @returns Callback to stop polling function
*/
pollQueries(onQuery, options = {}) {
const opt = {
...this.options,
...options
};
const knownQueryIds = new Set();
let isChecking = false;
const checkNewQueries = async () => {
if (isChecking) return;
isChecking = true;
const filtered = (await this.getQueries(opt)).filter(({
id
}) => !knownQueryIds.has(id)).filter(query => options.includeResponded === true || query.decodedResponse === '');
filtered.forEach(query => knownQueryIds.add(query.id));
isChecking = false;
await Promise.all(filtered.map(query => onQuery(query)));
};
checkNewQueries();
const idPromise = (async _opt$interval => {
const interval = (_opt$interval = opt.interval) !== null && _opt$interval !== void 0 ? _opt$interval : await _getPollInterval('micro-block', opt);
return setInterval(async () => checkNewQueries(), interval);
})();
return async () => {
const id = await idPromise;
clearInterval(id);
};
}
/**
* Respond to a query
* @param queryId - Oracle query id
* @param response - The response to query
* @param options - Options object
*/
async respondToQuery(queryId, response, options = {}) {
const opt = {
...this.options,
...options
};
const oracleRespondTx = await buildTxAsync({
_isInternalBuild: true,
...opt,
tag: Tag.OracleRespondTx,
oracleId: this.address,
queryId,
response
});
return sendTransaction(oracleRespondTx, {
...opt,
onAccount: this.account
});
}
/**
* Respond to queries to oracle based on callback value
* @param getResponse - Callback to respond on query
* @param options - Options object
* @param options.interval - Poll interval (default: 5000)
* @returns Callback to stop polling function
*/
handleQueries(getResponse, options = {}) {
if (_classPrivateFieldGet(_handleQueriesPromise, this) != null) {
throw new LogicError('Another query handler already running, it needs to be stopped to run a new one');
}
const opt = {
...this.options,
...options
};
let queuePromise = Promise.resolve();
const handler = async q => {
const response = await getResponse(q);
const respondPromise = queuePromise.then(async () => this.respondToQuery(q.id, response, opt));
queuePromise = respondPromise.then(() => {}, () => {});
await respondPromise;
};
_classPrivateFieldSet(_handleQueriesPromise, this, Promise.resolve());
const stopPoll = this.pollQueries(async query => {
const promise = handler(query);
if (_classPrivateFieldGet(_handleQueriesPromise, this) == null) throw new UnexpectedTsError();
_classPrivateFieldSet(_handleQueriesPromise, this, _classPrivateFieldGet(_handleQueriesPromise, this).then(async () => promise).then(() => {}, () => {}));
return promise;
}, opt);
return async () => {
stopPoll();
await _classPrivateFieldGet(_handleQueriesPromise, this);
_classPrivateFieldSet(_handleQueriesPromise, this, undefined);
};
}
}
//# sourceMappingURL=Oracle.js.map