Skip to content

Commit

Permalink
feat(oracle): add getQueries to OracleBase
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Feb 24, 2025
1 parent df2c350 commit 0af61da
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 16 deletions.
2 changes: 1 addition & 1 deletion docs/guides/oracles.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 2 additions & 4 deletions src/oracle/Oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Tag.OracleRegisterTx, 'accountId' | 'queryFormat' | 'responseFormat'>,
Expand Down Expand Up @@ -96,10 +96,8 @@ export default class Oracle extends OracleBase {
const checkNewQueries = async (): Promise<void> => {
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;
Expand Down
15 changes: 11 additions & 4 deletions src/oracle/OracleBase.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { decode, Encoded } from '../utils/encoder.js';
import Node from '../Node.js';

type OracleQueryNode = Awaited<
ReturnType<Node['getOracleQueriesByPubkey']>
>['oracleQueries'][number];
type OracleQueryNode = Awaited<ReturnType<Node['getOracleQueryByPubkeyAndQueryId']>>;
export interface OracleQuery extends OracleQueryNode {
// TODO: type should be corrected in node api
id: Encoded.OracleQueryId;
decodedQuery: string;
decodedResponse: string;
}

export function decodeQuery(queryEntry: OracleQueryNode): OracleQuery {
function decodeQuery(queryEntry: OracleQueryNode): OracleQuery {
return {
...queryEntry,
id: queryEntry.id as Encoded.OracleQueryId,
Expand Down Expand Up @@ -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<OracleQuery[]> {
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
Expand Down
5 changes: 1 addition & 4 deletions src/oracle/OracleClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
32 changes: 29 additions & 3 deletions test/integration/oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
decode,
encode,
Encoding,
Encoded,
ORACLE_TTL_TYPES,
Oracle,
OracleClient,
Expand Down Expand Up @@ -84,6 +83,33 @@ describe('Oracle', () => {
expect(await pollPromise).to.eql(queries);
});

let query4: Awaited<ReturnType<OracleClient['getQuery']>>;
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);
Expand All @@ -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);
});
Expand Down

0 comments on commit 0af61da

Please sign in to comment.