Skip to content

Commit

Permalink
feat: introduce new RPC methods to handle pending interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
sarvalabs-harshrastogi committed Dec 5, 2023
1 parent 7c5e90f commit f30514c
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 6 deletions.
10 changes: 10 additions & 0 deletions docs/source/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ Account Methods

.. autofunction:: getRegistry

.. autofunction:: getNewTesseractsByAccountFilter

Execution Methods
~~~~~~~~~~~~~~~~~

Expand All @@ -287,6 +289,14 @@ Query Methods

.. autofunction:: getAccounts

.. autofunction:: getNewTesseractFilter

.. autofunction:: getPendingInteractionFilter

.. autofunction:: getFilterChanges

.. autofunction:: removeFilter

Event Methods
~~~~~~~~~~~~~

Expand Down
95 changes: 91 additions & 4 deletions packages/js-moi-providers/__tests__/jsonrpc-provider.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Signer } from "js-moi-signer";
import { AssetCreationReceipt, AssetStandard, hexToBN, IxType } from "js-moi-utils";
import { JsonRpcProvider } from "../dist/jsonrpc-provider";
import { InteractionReceipt } from "../types/jsonrpc";
import { Filter, InteractionReceipt } from "../types/jsonrpc";
import { initializeWallet } from "./utils/utils";

describe("Test JsonRpcProvider Query Calls", () => {
const address = "0xf350520ebca8c09efa19f2ed13012ceb70b2e710241748f4ac11bd4a9b43949b";
const mnemonic = "mother clarify push liquid ordinary social track brief exit fiction wheat forward";
const address = "0x2c1fe83b9d6a5c81c5e6d4da20d2d0509ac3c1eb154e5f5b1fc7d5fd4a03b9cc";
const mnemonic = "cushion tissue toss meadow glare math custom because inform describe vacant combine";
let provider:JsonRpcProvider;
let ixHash: string;
let signer: Signer;
let ixReceipt: InteractionReceipt

beforeAll(async() => {
provider = new JsonRpcProvider('http://localhost:1600');
const signer = await initializeWallet(provider, mnemonic)
signer = await initializeWallet(provider, mnemonic)
const nonce = await signer.getNonce();
const ixResponse = await signer.sendInteraction({
type: IxType.ASSET_CREATE,
Expand Down Expand Up @@ -241,4 +243,89 @@ describe("Test JsonRpcProvider Query Calls", () => {
expect(accounts.length).toBeGreaterThanOrEqual(2)
});
});

describe("getNewTesseractFilter", () => {
it("should return the filter object containing the filter id", async () => {
const filter = await provider.getNewTesseractFilter();

expect(filter).toBeDefined();
expect(filter).toHaveProperty("id");
expect(typeof filter.id).toBe("string");
});
});

describe("getNewTesseractsByAccountFilter", () => {
it("should return a filter object containing filter id", async () => {
const filter = await provider.getNewTesseractsByAccountFilter(address);

expect(filter).toBeDefined();
expect(filter).toHaveProperty("id");
expect(typeof filter.id).toBe("string");
})
});

describe("getPendingInteractionFilter", () => {
it("should return a filter object containing filter id", async () => {
const filter = await provider.getPendingInteractionFilter();

expect(filter).toBeDefined();
expect(filter).toHaveProperty("id");
expect(typeof filter.id).toBe("string");
})
});

describe("removeFilter", () => {
it("should a return a object containing status of removal", async () => {
const filter = await provider.getNewTesseractsByAccountFilter(address);

const result = await provider.removeFilter(filter);

expect(result).toBeDefined();
expect(result).toHaveProperty("status");
expect(result.status).toBe(true);
})

it("should return a object with status false when filter is deleted or not exist", async () => {
const NOT_EXISTING_FILTER_ID = "678384f8-04e4-4984-9d51-44bfa5b185eb"
const filter: Filter = {
id: NOT_EXISTING_FILTER_ID
}

const result = await provider.removeFilter(filter);

expect(result).toBeDefined();
expect(result).toHaveProperty("status");
expect(result.status).toBe(false);
})
});

describe("getFilterChanges", () => {
it("should return null when no changes made", async () => {
const filter = await provider.getNewTesseractFilter();
const result = await provider.getFilterChanges(filter);
expect(result).toBeNull();
});

it("should return an array of terreracts", async () => {
const nonce = await signer.getNonce();
const filter = await provider.getNewTesseractFilter();
const ixResponse = await signer.sendInteraction({
type: IxType.ASSET_CREATE,
nonce: nonce,
fuel_price: 1,
fuel_limit: 200,
payload: {
standard: AssetStandard.MAS0,
symbol: "TESTING",
supply: 1248577
}
});

await Promise.all([ixResponse.wait(), ixResponse.result()])
const tesseracts = await provider.getFilterChanges(filter);

expect(Array.isArray(tesseracts)).toBeTruthy()
expect(Array.length).toBeGreaterThanOrEqual(1);
})
});
});
7 changes: 6 additions & 1 deletion packages/js-moi-providers/src/abstract-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Tesseract, Interaction } from "js-moi-utils";
import { EventType, Listener } from "../types/event";
import { AccountState, AccountMetaInfo, AssetInfo, ContextInfo, Options, TDU,
InteractionRequest, InteractionResponse, InteractionReceipt, Content, Status,
Inspect, ContentFrom, Encoding, Registry } from "../types/jsonrpc";
Inspect, ContentFrom, Encoding, Registry, Filter, DeletionStatus } from "../types/jsonrpc";

/**
* Abstract class representing a provider for interacting with the MOI protocol.
Expand Down Expand Up @@ -40,6 +40,11 @@ export abstract class AbstractProvider {
abstract getPeers(): Promise<string[]>
abstract getDBEntry(key: string): Promise<string>
abstract getAccounts(): Promise<string[]>
abstract getNewTesseractFilter(): Promise<Filter>
abstract getNewTesseractsByAccountFilter(address: string): Promise<Filter>
abstract getPendingInteractionFilter(): Promise<Filter>
abstract getFilterChanges<T extends any>(filter: Filter): Promise<T>
abstract removeFilter(filter: Filter): Promise<DeletionStatus>

// Event Emitter (ish)
abstract on(eventName: EventType, listener: Listener): AbstractProvider;
Expand Down
116 changes: 115 additions & 1 deletion packages/js-moi-providers/src/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ InteractionReceipt, InteractionParams, InteractionResponse,
LogicManifestParams, Options, RpcResponse, StorageParams, TDU, TesseractParams,
Content, AccountStateParams, DBEntryParams, ContentFrom, Status,
Inspect, Encoding, AccountMetaInfoParams, InteractionByTesseractParams,
Registry, TDUResponse } from "../types/jsonrpc";
Registry, TDUResponse, Filter, DeletionStatus } from "../types/jsonrpc";
import { AbstractProvider } from "./abstract-provider";
import Event from "./event";

Expand Down Expand Up @@ -358,6 +358,120 @@ export class BaseProvider extends AbstractProvider {
}
}

/**
* Initializes a filter for retrieving newly detected terreracts.
* The filter setup triggers a 1-minute timeout period, and with each subsequent query,
* the timeout is reset to 1 minute.
*
* @returns {Promise<string[]>} An object containing the filter id for the NewTesseractFilter.
*/
public async getNewTesseractFilter(): Promise<Filter> {
try {
const params = null;

const response: RpcResponse = await this.execute("moi.NewTesseractFilter", params);

return this.processResponse(response);
} catch (error) {
throw error;
}
}

/**
* Initiates a filtering mechanism to fetch recently identified tesseracts
* associated with a specific account. The filter setup triggers a 1-minute
* timeout period, and with each subsequent request, the timeout is reset to 1 minute.
*
* @param {string} address - The address of the target account for which new tesseracts are filtered.
* @returns {Promise<string[]>} An array containing the filter id for the NewTesseractFilter.
* @throws {Error} if there is an error executing the RPC call.
*/
public async getNewTesseractsByAccountFilter(address: string): Promise<Filter> {
try {
const params = {
address: address
};

const response: RpcResponse = await this.execute("moi.NewTesseractsByAccountFilter", params);

return this.processResponse(response);
} catch (error) {
throw error;
}
}

/**
*
* @returns {Promise<Filter>} A object containing the Filter ID for PendingIxnsFilter
* @throws {Error} if there is an error executing the RPC call.
*/
public async getPendingInteractionFilter(): Promise<Filter> {
try {
const params = null;

const response: RpcResponse = await this.execute('moi.PendingIxnsFilter', params);

return this.processResponse(response);
} catch (error) {
throw error;
}
}

/**
* Removes a filter.
*
* @param {Filter} filter - The object containing the Filter ID of the filter to be removed.
*
* @returns {Promise<DeletionStatus>} Resolves to object if the filter is successfully removed, otherwise false.
* @throws {Error} Throws an error if there is an issue executing the RPC call.
*/
public async removeFilter(filter: Filter): Promise<DeletionStatus> {
try {
const params = {
id: filter.id
};

const response: RpcResponse = await this.execute("moi.RemoveFilter", params);

return this.processResponse(response);
} catch (error) {
throw error;
}
}


/**
* Retrieves all filter changes since the last poll.
*
* The specific result varies depending on the type of filter used.
*
* @param {Filter} filter - The filter object for which changes are to be retrieved.
*
* @returns {Promise<T>} A promise that resolves to an object containing information about the changes made to the specified filter since the last poll. The structure of the object is determined by the type of filter provided.
* @throws {Error} Throws an error if there is an issue executing the RPC call.
*
* @template T - The type of the object returned, dependent on the provided filter.
*/
async getFilterChanges<T extends any>(filter: Filter): Promise<T> {
try {
const params = {
id: filter.id
};

const response = await this.execute("moi.GetFilterChanges", params);

if(response.result.data === null) {
return response.result.data;
}

console.log(response)

return this.processResponse(response);
} catch (error) {
throw error;
}
}

/**
* Retrieves a Tesseract for a specific address.
*
Expand Down
8 changes: 8 additions & 0 deletions packages/js-moi-providers/types/jsonrpc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ export interface ContentFrom {
queued: Map<number | bigint, InteractionInfo>;
}

export interface Filter {
id: string;
}

export interface DeletionStatus {
status: boolean;
}

export interface Status {
pending: number | bigint;
queued: number | bigint;
Expand Down

0 comments on commit f30514c

Please sign in to comment.