From 0af61da9c2a229aa6459881f601aa5479b39fe84 Mon Sep 17 00:00:00 2001 From: Denis Davidyuk Date: Tue, 28 Jan 2025 22:13:20 +0100 Subject: [PATCH] feat(oracle): add `getQueries` to OracleBase --- docs/guides/oracles.md | 2 +- src/oracle/Oracle.ts | 6 ++---- src/oracle/OracleBase.ts | 15 +++++++++++---- src/oracle/OracleClient.ts | 5 +---- test/integration/oracle.ts | 32 +++++++++++++++++++++++++++++--- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/docs/guides/oracles.md b/docs/guides/oracles.md index efbe9a0660..cdcd36780b 100644 --- a/docs/guides/oracles.md +++ b/docs/guides/oracles.md @@ -168,7 +168,7 @@ Both Oracle and OracleClient have methods to get their state from the node. `Oracle:getState`, `OracleClient:getState` returns the same value as `Node:getOracleByPubkey`, but without arguments (it uses the oracle address provided in the constructor). -`Oracle:getQuery`, `OracleClient:getQuery` corresponds to `Node:getOracleQueryByPubkeyAndQueryId`, adding `decodedQuery`, `decodedResponse` based on the oracle type. +`Oracle:getQuery`, `OracleClient:getQuery` corresponds to `Node:getOracleQueryByPubkeyAndQueryId`, adding `decodedQuery`, `decodedResponse` based on the oracle type. In the same way `Oracle:getQueries`, `OracleClient:getQueries` corresponds to `Node:getOracleQueriesByPubkey`. ## Example applications diff --git a/src/oracle/Oracle.ts b/src/oracle/Oracle.ts index b08bc11822..7a5ecbf692 100644 --- a/src/oracle/Oracle.ts +++ b/src/oracle/Oracle.ts @@ -6,7 +6,7 @@ import { _getPollInterval } from '../chain.js'; import { sendTransaction, SendTransactionOptions } from '../send-transaction.js'; import Node from '../Node.js'; import AccountBase from '../account/Base.js'; -import OracleBase, { OracleQuery, decodeQuery } from './OracleBase.js'; +import OracleBase, { OracleQuery } from './OracleBase.js'; interface OracleRegisterOptions extends BuildTxOptions, @@ -96,10 +96,8 @@ export default class Oracle extends OracleBase { const checkNewQueries = async (): Promise => { if (isChecking) return; isChecking = true; - const queries = (await opt.onNode.getOracleQueriesByPubkey(this.address)).oracleQueries ?? []; - const filtered = queries + const filtered = (await this.getQueries(opt)) .filter(({ id }) => !knownQueryIds.has(id)) - .map((query) => decodeQuery(query)) .filter((query) => options.includeResponded === true || query.decodedResponse === ''); filtered.forEach((query) => knownQueryIds.add(query.id)); isChecking = false; diff --git a/src/oracle/OracleBase.ts b/src/oracle/OracleBase.ts index 929b458a90..5b87b7cda6 100644 --- a/src/oracle/OracleBase.ts +++ b/src/oracle/OracleBase.ts @@ -1,9 +1,7 @@ import { decode, Encoded } from '../utils/encoder.js'; import Node from '../Node.js'; -type OracleQueryNode = Awaited< - ReturnType ->['oracleQueries'][number]; +type OracleQueryNode = Awaited>; export interface OracleQuery extends OracleQueryNode { // TODO: type should be corrected in node api id: Encoded.OracleQueryId; @@ -11,7 +9,7 @@ export interface OracleQuery extends OracleQueryNode { decodedResponse: string; } -export function decodeQuery(queryEntry: OracleQueryNode): OracleQuery { +function decodeQuery(queryEntry: OracleQueryNode): OracleQuery { return { ...queryEntry, id: queryEntry.id as Encoded.OracleQueryId, @@ -42,6 +40,15 @@ export default class OracleBase { return opt.onNode.getOracleByPubkey(this.address); } + /** + * Get oracle queries from the node + * @param options - Options object + */ + async getQueries(options: { onNode?: Node } = {}): Promise { + const opt = { ...this.options, ...options }; + return (await opt.onNode.getOracleQueriesByPubkey(this.address)).oracleQueries.map(decodeQuery); + } + /** * Get oracle query entry from the node * @param queryId - Oracle query ID diff --git a/src/oracle/OracleClient.ts b/src/oracle/OracleClient.ts index 9512822e44..c25f73e2f1 100644 --- a/src/oracle/OracleClient.ts +++ b/src/oracle/OracleClient.ts @@ -78,10 +78,7 @@ export default class OracleClient extends OracleBase { let ttl; let response; do { - ({ response, ttl } = await opt.onNode.getOracleQueryByPubkeyAndQueryId( - this.address, - queryId, - )); + ({ response, ttl } = await this.getQuery(queryId, opt)); const responseBuffer = decode(response as Encoded.OracleResponse); if (responseBuffer.length > 0) return responseBuffer.toString(); await pause(interval); diff --git a/test/integration/oracle.ts b/test/integration/oracle.ts index fa5ea8ec30..cb08c50c1c 100644 --- a/test/integration/oracle.ts +++ b/test/integration/oracle.ts @@ -7,7 +7,6 @@ import { decode, encode, Encoding, - Encoded, ORACLE_TTL_TYPES, Oracle, OracleClient, @@ -84,6 +83,33 @@ describe('Oracle', () => { expect(await pollPromise).to.eql(queries); }); + let query4: Awaited>; + it('gets queries', async () => { + const res = await oracle.getQueries(); + expect(res).to.have.length(3); + query4 = res.find((q) => q.decodedQuery.includes('Berlin4'))!; + assertNotNull(query4); + expect(query4).to.eql({ + id: query4.id, + senderId: oracleClient.options.onAccount.address, + senderNonce: 3, + oracleId: oracle.address, + query: 'ov_eyJjaXR5IjogIkJlcmxpbjQifR/koho=', + response: 'or_Xfbg4g==', + ttl: query4.ttl, + responseTtl: { type: 'delta', value: 10 }, + fee: 0n, + decodedQuery: '{"city": "Berlin4"}', + decodedResponse: '', + }); + }); + + it('gets query', async () => { + expect(await oracle.getQuery(query4.id)).to.eql(query4); + const { decodedQuery, decodedResponse, ...q } = query4; + expect(q).to.eql(await aeSdk.api.getOracleQueryByPubkeyAndQueryId(oracle.address, query4.id)); + }); + it('can poll for responded queries', async () => { const { queryId } = await oracleClient.postQuery('{"city": "Berlin"}'); await oracle.respondToQuery(queryId, queryResponse); @@ -98,8 +124,8 @@ describe('Oracle', () => { const { queryId } = await oracleClient.postQuery('{"city": "Berlin"}'); await oracle.respondToQuery(queryId, queryResponse); - const query = await aeSdk.api.getOracleQueryByPubkeyAndQueryId(oracle.address, queryId); - expect(decode(query.response as Encoded.OracleResponse).toString()).to.equal(queryResponse); + const query = await oracle.getQuery(queryId); + expect(query.decodedResponse).to.equal(queryResponse); const response = await oracleClient.pollForResponse(queryId); expect(response).to.equal(queryResponse); });